一、环境准备
按照这里的教程安装,本次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目录中需要的东西:
其中src是我的rn代码目录,package.json就是react native的配置。
方法二:新建一个rn文件夹,在其中放入package.json然后命令行运行 npm i就可以了,package.json可以是从新建的react native项目中提取也可以从其它项目提取但注意把不要的插件去掉。
上图是pakage.json的部分插件依赖,如果不需要redux那么在拷贝package.json的时候就把"redux":"^4.0.0"去掉就好,(这里指的是用方法二创建rn,调用npm i之前)。
添加依赖,在原生Android工程的项目build.gradle中添加如下,这里使用的是相对路径实际中根据自己的项目调整
在app的build.gradle中添加implementation'com.facebook.react:react-native:+' ,在minifest中添加
三 、集成
在原生项目中集成RN也有两种方法
1、直接继承ReactActvity
用这种方法就跟react native官方文档中介绍的一样,我们新建一个Activity集成ReactActivity,重写Application继承ReacApplication。代码如下:
getMainComponentName返回的就是js代码中调用AppRegistry.registerComponent('Test', () => Test);注册的名字,这样就OK了。我们来看下效果:
2、自己实现ReactActivity
这里推荐先看这个干货满满,自定义Activity继承DefaultHardwareBackBtnHandler, PermissionAwareActivity然后添加ReactRootView到
我们的activity中即可,生命周期方法需要重写。
注意onResume中的方法,reactInstanceManager.onHostResume前一个参数接受this, 后一个参数接受物理返回按键事件
其中keyup重写是为了能在模拟器上按ctrl+m调出调试菜单。
代码中的reactInstanceManager使我们定义的JS管理类,因为如果直接继承ReactActivity的时候ReactActivity内部会到ReactNativeHost中去取reactInstanceManager,而我们是没有继承ReactActivity所以我们得自己定义。
其中setJSBUndleFileName就是rn目录下入口文件的名字(index.android.js),上面代码的意思是如果是如果是调试模式下那么js代码就冲入口文件
index.android.js里面取。我们还有调用了setJSBundleFile这个是设置js文件目录,当不是调试模式的时候就会从这里面取bundle文件
看下实际运行效果图:
四、热更新
因为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文件夹下回生成相关文件以及文件夹,
3、点击Android原生项目中运行按钮(这里我怕将js中splash页面的代码改为不管怎么样都跳home页面,所以看不到登录页了)。
上面其实原本是有图片,但为什么没有,因为我们打bundle包的时候图片应该放到res文件夹下,但是我们放到了asset文件夹下了系统找不到
具体的可以看这里,我们可以将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卡根目录
5、加载更新文件
代码地址:https://github.com/yaozhukuang/android_rn_demo
参考资料:
react native 实战系列教程之热更新原理分析与实现
React-Native 图片热更新初探