查阅网上资源和博客,全部是在原生的基础上一点一点的加文件实现使原生项目变成React Native项目,步骤较多,比较复杂,容易出现各种问题,对于项目不是很大,文件目录不是过于复杂的原生项目尝试利用先新建React Native项目,然后将原生代码集成进去的办法(基于Android平台、IOS类似)。
一、打开现有项目
@H_403_21@利用Android Studio打开现有原生项目,如下图所示。
@H_403_21@
@H_403_21@
二、初始化一个React Native项目
这里不再赘述,现在书籍或者网上相关文档很多,跑一遍测试能否正常运行。
三、更换包名及appid
@H_403_21@如果新建完成后的React Native项目中android目录中的包名和appid不一致,可以将包名和appid修改,然后重新跑一遍工程检测是否能够运行。这样为了做到和之前原生代码一致,如果没有此方面需求或者新建完成后的项目包名和appid都一样则可以跳过此步骤。
@H_403_21@
四、将原生项目中指定目录copy到React Native项目中
@H_403_21@主要涉及java目录、res目录、assets目录、jniLibs与lib目录、build.gradle与AndroidManifest配置文件,如下图所示,左侧为原生工程目录,右侧为React Native中的android目录。
@H_403_21@
@H_403_21@最关键并且需要注意的是build.gradle与AndroidManifest两个配置文件,build.gradle文件中的依赖只移动红色区域部分依赖,蓝色部分为React Native项目初始化化时自动生成的,不用动,如下图所示。
@H_403_21@AndroidManifest配置文件中需要移动<uses-permission android:name="android.permission.INTERNET" />类似各种权限的部分和注册的Activity部分,如果lib下的jar包不能识别,需要右键jar然后add as library。 复制完毕以上目录和文件再用Android Studio跑一遍,测试程序能否跑通。
@H_403_21@
五、编写代码
@H_403_21@(1) 参见React Native与原生混编博客,可以实现从React Native到原生或者原生到React Native页面,这里不再赘述。
@H_403_21@
@H_403_21@(2) React Native中MainApplication与之前原生代码中XXXApplication的代码合并,这个是要注意的地方,没有冲突的情况下,建议直接将XXXApplication的代码粘贴到React@H_403_21@Native自动生成的MainApplication中,如果有代码冲突,具体问题具体分析。
@H_403_21@
@H_403_21@(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); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostPause(); } } @Override protected void onResume() { super.onResume() if (mReactInstanceManager != null) { mReactInstanceManager.onHostResume(this,this); } } @Override protected void onDestroy() { super.onDestroy(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostDestroy(); } } @Override public void onBackPressed() { if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } @Override public 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的代码。
六、遇到的问题及解决办法
@H_403_21@(1) 终端出现如下日志,bundle文件才算正式生成成功。
@H_403_21@(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/的方式)
@H_403_21@(3) ReactNative页面是基于原生的,原生调用的是assets目录下打包好的bundle文件,所以利用命令打包之前js文件最好是准确无误可以跑通的,因为js每调试一次就得利用命令生成一次,目前在网上还没有查到更好的方式(欢迎留言指导)。目前尝试出的一个比较好的方式是:在注册文件AndroidManifest中设置启动页为React Native自动生成的MainActivity,这样启动时就能调试js代码。
原文链接:https://www.f2er.com/react/305534.html