原生代码中接入React Native

35 篇文章 0 订阅
27 篇文章 0 订阅

       查阅网上资源和博客,全部是在原生的基础上一点一点的加文件实现使原生项目变成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);
}
@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的代码。


六、遇到的问题及解决办法

(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代码。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值