Android原生项目中嵌入React Native页面
有两种方式集成到Activity中
第一种是通过把js文件当成是布局的方式,通过ReactInstanceManager管理js
第二种是通过继承ReactNativeActivity
配置
app中build.gradle添加依赖
implementation "com.facebook.react:react-native:0.55.4"
目前为止0.56.0是最新版本,但是一直会遇到Unable to resolve module AccessibilityInfo
的错误,据说是这个版本对windows的一个兼容问题,解决了半天,放弃,降版本。
defaultConfig中加入对ndk的支持
ndk {
//选择要添加的对应cpu类型的.so库。
abiFilters 'armeabi', "armeabi-v7a", "x86"
}
截此为止,应该是编不过的,因为reactnative的minSdkVersion是16,而我默认创建的是15
添加reactnative配置文件等
生成package.json配置文件
在android studio中的终端中运行
yarn init--生成package.json
在package.json中加入
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
},
不加的话npm start会报错
加入react native
yarn add react-native@0.55.4
yarn add react@16.4.2
Module的build.gradle中的allprojects中
maven {
url "$rootDir/node_modules/react-native/android"
}
这个url主要是看刚刚加yarn add react-native时node_modules文件夹的位置。之前的所有操作是在项目根目录,生成的所有文件也都在根目录,所以是这个路径。
权限
Androidmainfeast.xml中给网络权限等和声明DevSettingsActivity这个界面是reactnative调试的时候的设置界面,简而言之一般就是摇一摇出来连网的那个界面。
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" /> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
bundle文件
需要在mian路径下新建一个assets文件夹
在开发过程中只有一个空文件夹不会报错,因为开发过程中一般会连接wifi在同一个局域网内传输,只要reload一下,bundle文件就会自动生成并打包到手机里面
但是需要正式上线的时候需要注意一定要将bundle打包在文件夹里面,这样assets中会有index.android.bundle和index.android
react-native bundle --platform android --dev false --entry-file index.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res
index.js文件
在项目根目录下建index.js,这里的话我是用了reactnative中文网上集成到原生项目给index.js
import React from "react"; import { AppRegistry, StyleSheet, Text, View } from "react-native"; class HelloWorld 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("MyReactNativeApp", () => HelloWorld);
第一种通过ReactInstanceManager管理js
需要注意的一点是如果AppTheme中有actionbar的话,那么第一种方式还是会有actionbar的,
但是第二种方式集成ReactActivity的会覆盖
主要方法有onCreate中的
mReactRootView = new ReactRootView(this); mReactInstanceManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setBundleAssetName("index.android.bundle")//bundle名称 .setJSMainModulePath("index") .addPackage(new MainReactPackage()) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); // 注意这里的MyReactNativeApp必须对应“index.js”中的 // “AppRegistry.registerComponent()”的第一个参数 mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null); setContentView(mReactRootView);
Activity需要实现DefaultHardwareBackBtnHandler,否则触摸事件会有问题
第二种通过继承ReactActivity
实现ReactApplication
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 protected String getJSMainModuleName() { return "index"; } @Nullable @Override protected String getBundleAssetName() { return "index.android.bundle"; } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this,false); } }
然后再AndroidMainFeast.xml中Application节点要加android:name=".MainApplication",这样才能用上MainApplication
Activity中继承ReactActivity,重写方法
@Nullable @Override protected String getMainComponentName() { return "MyReactNativeApp";//MyReactApp是index.js中AppRegistry注册的组件名称 }
总结
至此两种Activity集成的方法就说完了,不足望指正。