原生代码中接入React Native
来源:互联网 发布:mac系统密码忘记 编辑:程序博客网 时间:2024/05/17 06:05
查阅网上资源和博客,全部是在原生的基础上一点一点的加文件实现使原生项目变成React Native项目,步骤较多,比较复杂,容易出现各种问题,对于项目不是很大,文件目录不是过于复杂的原生项目尝试利用先新建React Native项目,然后将原生代码集成进去的办法(基于Android平台、IOS类似)。
一、打开现有项目
利用Android Studio打开现有原生项目,如下图所示。
二、初始化一个React Native项目
这里不再赘述,现在书籍或者网上相关文档很多,跑一遍测试能否正常运行。
三、更换包名及appid
如果新建完成后的React Native项目中android目录中的包名和appid不一致,可以将包名和appid修改,然后重新跑一遍工程检测是否能够运行。这样为了做到和之前原生代码一致,如果没有此方面需求或者新建完成后的项目包名和appid都一样则可以跳过此步骤。
四、将原生项目中指定目录copy到React Native项目中
主要涉及java目录、res目录、assets目录、jniLibs与lib目录、build.gradle与AndroidManifest配置文件,如下图所示,左侧为原生工程目录,右侧为React Native中的android目录。
最关键并且需要注意的是build.gradle与AndroidManifest两个配置文件,build.gradle文件中的依赖只移动红色区域部分依赖,蓝色部分为React Native项目初始化化时自动生成的,不用动,如下图所示。
AndroidManifest配置文件中需要移动<uses-permission android:name="android.permission.INTERNET" />类似各种权限的部分和注册的Activity部分,如果lib下的jar包不能识别,需要右键jar然后add as library。 复制完毕以上目录和文件再用Android Studio跑一遍,测试程序能否跑通。
五、编写代码
(1) 参见React Native与原生混编博客,可以实现从React Native到原生或者原生到React Native页面,这里不再赘述。
(2) React Native中MainApplication与之前原生代码中XXXApplication的代码合并,这个是要注意的地方,没有冲突的情况下,建议直接将XXXApplication的代码粘贴到React Native自动生成的MainApplication中,如果有代码冲突,具体问题具体分析。
(3) 在原生代码MainActivity的恰当位置或者想用React Native去实现的页面编写跳转React Native的代码逻辑。
Intent intent = new Intent(MainActivity.this,ReactNativeActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
(4) 在ReactNativeActivity中去实现DefaultHardwareBackBtnHandler类,并且去覆写指定方法。onCreate方法中编写加载bundle文件代码及赋值一些设置信息。完整代码如下图所示。
public class ReactNativeActivity extends Activity 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, "ReactNativeProjectName", null);setContentView(mReactRootView);}@Overridepublic void invokeDefaultOnBackPressed() {super.onBackPressed();}@Overrideprotected void onPause() {super.onPause(); if (mReactInstanceManager != null) {mReactInstanceManager.onHostPause();} }@Overrideprotected void onResume() {super.onResume() if (mReactInstanceManager != null) {mReactInstanceManager.onHostResume(this, this);} }@Overrideprotected void onDestroy() {super.onDestroy(); if (mReactInstanceManager != null) {mReactInstanceManager.onHostDestroy();} }@Overridepublic void onBackPressed() {if (mReactInstanceManager != null) {mReactInstanceManager.onBackPressed();} else {super.onBackPressed();} }@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_MENU &&mReactInstanceManager != null) {mReactInstanceManager.showDevOptionsDialog(); return true;}return super.onKeyUp(keyCode, event);}}
注意setBundleAssetName中index.android.bundle的全称,这需要和android工程目录下assets一致;setJSMainModuleName中index.android要与React Native侧的首个启动js页名称一致;startReactApplication中的第二个参数要与React Native侧的注册组件名称一致。
(5) 原生代码唤起React Native侧代码程序入口完全在(4)中完成,这时建立新工程时自动生成的MainActivity如下图所示完全没有用了,可以考虑删除掉。
(6) 终端到项目根目录下,执行react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/。目的是在android的工程目录下assets中生成index.android.bundle文件和index.android.bundle.meta文件。也就是说所有编写的React Native代码会打包进index.android.bundle文件中,供原生代码调用。
(7) 利用Android Studio运行该程序,点击,即可完成从原生到React Native页面的跳转,原生代码中成功嵌入了React Native的代码。
六、遇到的问题及解决办法
(1) 终端出现如下日志,bundle文件才算正式生成成功。
(2) 修改package.json文件和终端执行生成bundle文件命令,二选一,不要二者都操作一遍。(本例是采用终端键入react-native bundle --platform android--dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/的方式)
(3) ReactNative页面是基于原生的,原生调用的是assets目录下打包好的bundle文件,所以利用命令打包之前js文件最好是准确无误可以跑通的,因为js每调试一次就得利用命令生成一次,目前在网上还没有查到更好的方式(欢迎留言指导)。目前尝试出的一个比较好的方式是:在注册文件AndroidManifest中设置启动页为React Native自动生成的MainActivity,这样启动时就能调试js代码。
- 原生代码中接入React Native
- Android原生项目接入React Native
- 原生接入React-Native实战之配置篇
- 4.React Native接入原生项目的一些问题
- iOS原生项目中集成React Native
- iOS原生项目中集成React Native
- iOS原生项目中集成React Native
- React Native嵌入Android原生项目中
- iOS原生项目中集成React Native
- 如何在已有的iOS APP原生代码中整合React Native
- React Native原生视图
- 在Android原生中嵌入React Native,进而React Native调用原生
- 在Android原生中嵌入React Native,进而React Native调用原生
- react native android 高德地图原生代码编写
- React Native 调用原生Android/iOS代码实现拨号功能
- 原生Android项目中集成React native页面
- iOS在原生项目中插入React Native(最终版)
- 如何把React Native嵌入到原生android应用中
- JS组件系列——两种bootstrap multiselect组件大比拼
- 转:对称加密与非对称加密
- 【原创】【NOIP】火柴棒等式
- JS自定义选择器
- 输出文件
- 原生代码中接入React Native
- 微信号开通检测软件全面对比(2017)
- 【LIS】 洛谷 HAOI2007 上升序列(Longest Increasing Subsequence)
- 前台如何将多个json对象传入java后台(转)
- Android在外接物理键盘时,如何强制调用系统软键盘
- poj_3278 Catch That Cow(bfs)
- 在Java中如何读取xml文件---DOM解析
- 一些常用的符号小结
- Number对象、Math数学对象、数组对象