现有原生Android应用集成RN(React Native Android)开发环境
环境搭建
因为本人使用的是macbook,所以只记录mac上的搭建过程,windows自行观看教程。本文只讲把RN集成到现有的原生开发环境,如果新建的RN android项目,应该很简单吧?
基础软件包
Homebrew,Nodejs,Watchman这些工具包都是必备的。装完上面的软件(应该本来就有吧?),再有就是RN相关的了,react-native-cli,RN的命令行工具
基础开发运行环境
- JDK 1.8
- AS 2.0
- Android SDK 6.0 API23
集成到原生项目中
- 先说下基本注意事项:命令执行的目录不能乱,要注意工程目录和app
工程目录下,执行
npm init
,把该项目初始化为RN项目,命令行中会出现提示,让输入工程的相关信息,第一个为name,不能大写,这个name为RN界面的入口。后面的都先不设置,一路回车,最后问你yes or no,输入yes!工程就初始化好了,工程目录会多一个package.json文件,这个就是RN的配置文件,刚刚输入的信息都在里面。大概长这个样子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16{
"name": "leanrn1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.0.0-alpha.12",
"react-native": "^0.48.2"
}
}生成后,scripts节点中没有start节点,要补上,测试用的。
下载RN库。在工程目录下,执行
npm install --save react react-native
,新本的npm支持使用–save保持安装包是最新的。执行上述命令就形成了一个坑,下文有特意讲坑的地方,使用官方命令npm install --save react@16.0.0-alpha.12 react-native
可脱坑。不管是执行哪个命令吧,执行完后工程目录下会多出node_modules文件夹。- 接着输入
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
,下载这个配置文件我也不知道有啥用。flow是facebook的一种格式,这个配置文件是解析flow格式的json用的?- -! 在工程目录下新建一个index.android.js,内容可以copy官方教程中的,代码为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32'use strict';
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
class leanrn1 extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.hello}>Hello, World</Text>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
AppRegistry.registerComponent('leanrn1', () => leanrn1);其实这个就是RN的js文件了注意
AppRegistry.registerComponent('leanrn1', () => leanrn1);
中的leanrn1。配置android工程对RN库的依赖。在app中的build.gradle文件中配置
1
2
3
4
5
6dependencies节点中添加
compile "com.facebook.react:react-native:+"
android节点中添加(如果sync后有冲突的话)
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}在工程目录的build.gradle中的repositories添加
1
2
3
4maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/node_modules/react-native/android"
}url的目录位置就是工程目录中的node_modules位置,如果不对,请按自己情况修过,如果不会改,在mave中print一下url,慢慢改!然后再添加网络相关权限。据说6.0以后还要添加系统对话框权限,蒙层权限七七八八。
添加测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92package com.leanrn1.kahn.leanrn1;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "leanrn1", null);
setContentView(mReactRootView);
}
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause();
}
}
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy();
}
}
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
}
AndroidManifest.xml中添加
<activity
android:name=".MyReactActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
</activity>以上为测试代码
工程目录下运行
npm start
命令。该会开启一个本地的http服务器,对外提供的服务就是访问本机的8081端口就可以下载index.android.js文件。RN库本质就是加载js代码,转换成.bundle文件,解析.bundle文件生成原生库的控件。在Welcomeactivity中配置一下跳转,跳转到刚刚6的测试activity。- 最后,然后愉快的sync工程,运行项目。如果,没闪退,没报错,没红屏,那么恭喜你,自行去搜索RN的开发教程吧。下面的就不用看了。
坑
红屏系列
- Can’t find variable: __fbBatchedBridge
- 对不起,你的本地测试服务没开,请在项目根目录运行
npm start
- 对不起,你的本地测试服务没开,请在项目根目录运行
- Unable to load script from assets’index.android.bundle’……
- 这个就有点恶心了。要去main下新建assets文件夹,然后用命令从本地测试服务(
npm start
启动的)新建一个.bundle文件。curl "http://localhost:8081/index.android.bundle?platform=android" -o "android/app/src/main/assets/index.android.bundle"
,上面命令后面的“”是你的assets路径。再试试,不行就没招了。我试过,直接解决了这个问题,然后把这个文件删掉,再运行,还是可以,一脸懵逼啊,到底是不是这种方式解决的都不知道了。
- 这个就有点恶心了。要去main下新建assets文件夹,然后用命令从本地测试服务(
- Cannot read property ‘ReactCurrentOwner’ of undefined
- 一般是因为rn的版本不对。上面说到直接使用
npm install --save react react-native
下载的版本可能不对。使用该命令install时,如果版本不对,会出现一个警告,react版本不对,会告诉你一个对的版本。也可以去package.json文件中查看react节点的版本号,发现确实不是。使用警告中提示的版本再单独安装pm install -save react@16.0.0-alpha.12
,安装完后,再去看package.json,这回应该对了吧。
- 一般是因为rn的版本不对。上面说到直接使用
配置系列
- 如果用真机调试,可能要重定向一下手机访问的端口号。
- 使用命令
adb reverse tcp:8081 tcp:8081
。
- 使用命令
- 点击menu菜单,使用调试功能时闪退
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
配置之~
- 别忘了.gitignore(在该文件里添加排除项,node_modules/ 和 npm-debug.log)
- 如果想5.0以下运行,使用RN的activity继承AppCompatActivity。
- 闪退后打印爆出android.support.v4.net相关错误
- gradle.properties (在文件末尾添加,android.useDeprecatedNdk=true)
- app/build.gradle (将 ‘com.android.support:appcompat-v7:24.2.1’ 改为 ‘com.android.support:appcompat-v7:23.0.1’)
升级降级及版本核对
- 查看当前的RN版本,
react-native --version
,npm包中的版本信息使用npm info react-native
。 - 使用
react-native upgrade
命令可以直接升级。 - 升降级使用
npm install --save react-native@xxx
,xxx为具体版本,运行完后,再运行下2试试? - 在package.json中修改版本,再执行
npm install
也可达到升降级的效果。个人感觉还是直接指定版本比较靠谱。
##用到的命令汇总
1 | brew install watchman |