原生Android项目集成react native

一、环境准备

按照这里的教程安装,本次demo是在windows下使用。

二、创建工程

1、创建一个Android 工程Test。2、创建一个react native工程。工程目录大致如下:

其中Test目录就是创建的Android原生工程,rn目录就是react native工程目录(PS:我在实际应用过程中rn的名字是不能变的,最开始我取名叫

React Native结果在build.gradle中链接的时候找不到,不知道是不是我用的姿势不对,如果有知道的话请指正)。rn工程的创建有两种方法。

方法一:直接用react native init rn。我们rn目录中需要的东西:


原生Android项目集成react native_第1张图片

其中src是我的rn代码目录,package.json就是react native的配置。

方法二:新建一个rn文件夹,在其中放入package.json然后命令行运行 npm i就可以了,package.json可以是从新建的react native项目中提取也可以从其它项目提取但注意把不要的插件去掉。


原生Android项目集成react native_第2张图片
package.json

上图是pakage.json的部分插件依赖,如果不需要redux那么在拷贝package.json的时候就把"redux":"^4.0.0"去掉就好,(这里指的是用方法二创建rn,调用npm i之前)。

添加依赖,在原生Android工程的项目build.gradle中添加如下,这里使用的是相对路径实际中根据自己的项目调整

原生Android项目集成react native_第3张图片

在app的build.gradle中添加implementation'com.facebook.react:react-native:+' ,在minifest中添加增加调试菜单页面

三 、集成

在原生项目中集成RN也有两种方法

1、直接继承ReactActvity

用这种方法就跟react native官方文档中介绍的一样,我们新建一个Activity集成ReactActivity,重写Application继承ReacApplication。代码如下:

原生Android项目集成react native_第4张图片
MyReactActivity
原生Android项目集成react native_第5张图片
MyApplication

getMainComponentName返回的就是js代码中调用AppRegistry.registerComponent('Test', () => Test);注册的名字,这样就OK了。我们来看下效果:


原生Android项目集成react native_第6张图片
直接继承ReactActivity

2、自己实现ReactActivity

这里推荐先看这个干货满满,自定义Activity继承DefaultHardwareBackBtnHandler, PermissionAwareActivity然后添加ReactRootView到

我们的activity中即可,生命周期方法需要重写。


原生Android项目集成react native_第7张图片
设置ContentView


原生Android项目集成react native_第8张图片
重写生命周期方法

注意onResume中的方法,reactInstanceManager.onHostResume前一个参数接受this, 后一个参数接受物理返回按键事件

原生Android项目集成react native_第9张图片
返回按键事件,权限请求重写

其中keyup重写是为了能在模拟器上按ctrl+m调出调试菜单。

代码中的reactInstanceManager使我们定义的JS管理类,因为如果直接继承ReactActivity的时候ReactActivity内部会到ReactNativeHost中去取reactInstanceManager,而我们是没有继承ReactActivity所以我们得自己定义。


原生Android项目集成react native_第10张图片
reactInstanceManager管理类

其中setJSBUndleFileName就是rn目录下入口文件的名字(index.android.js),上面代码的意思是如果是如果是调试模式下那么js代码就冲入口文件

index.android.js里面取。我们还有调用了setJSBundleFile这个是设置js文件目录,当不是调试模式的时候就会从这里面取bundle文件


原生Android项目集成react native_第11张图片
获取js文件目录

看下实际运行效果图:


原生Android项目集成react native_第12张图片
打开自定义的react activity

四、热更新

因为js文件路径是可以由我们自定义的,所以实现热更新就很简单了,上面getJSBundleFile中我们先判断在getReactNativeDir中是否存在bundle

文件,如果有就加载如果没有就从assets中加载,所以我们把最新bundle文件放到getReactNativeDir中就实现简单的热更新了,下面来测试一下。

1、先把reactInstanceManager管理类中builder.setJSMainModulePath("index.android")去掉

2、将bundle文件生成到assets文件夹中,在rn文件下打开命令行运行react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output ../Test/app/src/main/assets/index.android.bundle --assets-dest ../Test/app/src/main/assets 参数大家应该能够看得懂 dev是否是调试模式,entry-file js的入口文件,bundle-output 生成的bundle文件路径,assets-dest 资源文件路径,我这里是将资源文件和bundle文件都生成到Android原生项目中的assets文件夹中了。命令运行成功后再Test项目的assets文件夹下回生成相关文件以及文件夹,

原生Android项目集成react native_第13张图片

3、点击Android原生项目中运行按钮(这里我怕将js中splash页面的代码改为不管怎么样都跳home页面,所以看不到登录页了)。


原生Android项目集成react native_第14张图片
运行效果图

上面其实原本是有图片,但为什么没有,因为我们打bundle包的时候图片应该放到res文件夹下,但是我们放到了asset文件夹下了系统找不到

具体的可以看这里,我们可以将assets文件全部拷贝到sd卡中这样就没问题了,下面上效果图:


原生Android项目集成react native_第15张图片
拷贝assets资源到sd卡

4、更新,我们菜单页的Test改为Hotfix,将图片换成红色的试试,然后打bundle包

    运行命令:react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output ./assets/index.android.bundle --assets-dest ./assets 这次将bundle文件和asset文件就生成在当前目录,将bundle和资源文件一起压缩后放到然后将文件压缩放到手机sd卡根目录

原生Android项目集成react native_第16张图片
图片和bundle压缩包

5、加载更新文件


原生Android项目集成react native_第17张图片
热更新

代码地址:https://github.com/yaozhukuang/android_rn_demo

参考资料:

react native 实战系列教程之热更新原理分析与实现

React-Native 图片热更新初探

你可能感兴趣的:(原生Android项目集成react native)