Android项目引入RN的步骤
之前在学习RN时,创建RN项目一般都是通过react-native init xxx来实现。最近需要在项目中运用到RN,查看官网的说明也不是很详细,网上也有很多帖子,但是也遇到很多坑,这篇主要是记录一下项目添加RN的步骤以及过程中遇的到问题和解决方法。都是固定的套路和步骤,没有太多技术含量,记录一下。
首先肯定是需要配置RN开发环境,这里就不再累赘。
一、项目根目录创建package.json cmd或者Terminal进入项目根目录,通过npm init
依次输入name(不能为大写) description author password等等,其中的name最为重要,其他的可以不用写。这个name对应接下来注册用到的必须一致,否则运行时会出现Module AppRegistry is not a registered callable module
和undefined is not an object(ecaluating 'ReactInternals.ReactCurrentOwner')
的错误。完成后会生成一个如下所示的json文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name": "aspactjdemo",
"version": "1.0.0",
"description": "aspactjdemo",
"main": "index.js",
"scripts": {
// 注意:这行启动脚本,生成json时并没有,需要手动粘贴上,粘贴时注意遵循json格式
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "jzm",
"license": "ISC",
"dependencies": {
"react": "^15.6.1",
"react-native": "^0.47.2"
}
}
二、添加react和react-native 模块 在根目录执行如下代码:npm install --save react react-native
下载react-native模块,时间较长,两分钟左右。执行完成后会出现下图的node_modules:
二、添加index.android.js文件到项目中: 这个就不用多说了,很简单,注意一下AppRegistry.registerComponent(‘aspactjdemo’, () => Demo)就行。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
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class Demo extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.android.js
</Text>
<Text style={styles.instructions}>
这是一个ReactNative界面,{'\n'}测试
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
// 这个名字必须要和第一步中的name一致,这个Demo对应 上面的Class Demo extends Component
AppRegistry.registerComponent('aspactjdemo', () => Demo);
三、添加ReactNative相关依赖
在app的build.gradle文件中添加react-native依赖库compile "com.facebook.react:react-native:+"
在project的build.gradle文件中添加react-native路径 注意:这里注意不要使用maven中的,因为我们使用的是我们本地的node_modules
1
2
3
4
5
6
7
8
9
10
11
allprojects {
repositories {
jcenter()
maven {
// All of React Native (JS, Android binaries) is installed from npm
// node_modules的路径检查一遍,复制网上帖子的
// url "$rootDir/../node_modules/react-native/android"给坑了,在重写Application时,找不到ReactApplictaion这个接口
url "$rootDir/node_modules/react-native/android"
}
}
}
同步,会报错:Error:Conflict with dependency 'com.google.code.findbugs:jsr305'. Resolved versions for app (3.0.0) and test app (2.0.1) differ.
解决方法:在module层的build.gradle中添加:1
2
3
4
5
6
7
android {
...
...
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.0'
}
}
四、添加相关权限和支持NDK:
在AndroidManifest.xml中添加如下代码:<uses-permission android:name="android.permission.INTERNET" />
1
2
3
4
5
6
7
8
9
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
}
gradle.properties:android.useDeprecatedNdk=true
五、添加reactnative组件: 1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
<com.facebook.react.ReactRootView
android:id="@+id/react_root_view"
android:layout_width="300dp"
android:layout_height="300dp"/>
</LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MainActivity extends AppCompatActivity {
ReactRootView react_root_view ;
ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
react_root_view = (ReactRootView) findViewById(R.id.react_root_view);
mReactInstanceManager =ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// aspectjdemo是项目名,需要和index.adnroid.js、json中的保持一致
react_root_view.startReactApplication(mReactInstanceManager, "aspectjdemo", null);
}
}
也可以通过Activity继承ReactActivity来实现。
六、添加DevSettingsActivity配置 <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
七、自定义Appliction 需要自定义Application然后去实现ReactApplication接口。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
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
七、 运行: Unable to load script form assets'index.android.bunlde'.Make sure your bundle is packaged correctly...
嗯是的,忘了开服务:进项目根目录,通过npm start
开启服务,摇一摇配置一下IP+端口。
也可以通过打包的方式生成bundle
main下创建assets
根目录下执行:react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output AspectJDemo/app/src/main/assets/index.android.bundle --assets-dest AspectJDemo/app
/src/main/res/
生成如下图两个文件,再运行就OK了,这种适合上线打包,平时的调试使用server较方便,在开发环境下,为方便调试,APP会在启动时从JS Server服务器将index.android.bundle文件加载到APP。。