上一篇和大家分享了如何在Android 现有App中集成React Native。今天这篇博客也是React Native中比较热门的内容 ---> 热更新部署。
Android原生App中我们实现热修复有很多种选择:Tinker、hotFix、Qzone的热更新等等。基本的思路都是大同小异的。React Native中的热更新有点像App的版本更新,也就是根据查询server端的版本和手机端目前App的版本进行对比,然后来执行是否更新的操作。根本原因在于React Native的加载启动机制:React Native会将一系列资源打包成js bundle文件,系统加载js bundle文件,解析并渲染。所以,React Native热更新的根本原理就是更换js bundle文件,并重新加载,新的内容就完美的展示出来了。微软为我们提供了CodePush来简化热更新的操作,但是由于速度等原因在国内并没有备受青睐。本篇内容就以自己服务器来更新的方式实现。
前面简单的说了些基本原理,接下来先上一张具体的更新流程图:
上面流程图中展示了如何实现更新的步骤,可以总结为如下几点:
进入App根据版本检查是否需要更新:
(1)更新:
下载最新JsBundle文件以及所需要的图片资源等,下载完成后解析最新JsBundle文件。
(2)不更新:
判断本地是否还有缓存的JsBundle文件:
1>存在:
本地存在JsBundle,即有过热更新操作。那么App直接加载在缓存目录下的JsBundle文件。
2>不存在:
本地不存在JsBundle,即之前从未有过热更新操作。那么App只能使用初始化时打包在assets目录下的index.android.bundle文件。
Ok,基本的流程大致就是以上步骤,下面我们来看下代码实现流程:
(1)
(2)
(3)
如何获取最新的bundle文件和图片资源呢?我们在RN项目根目执行以下命令来得到bundle文件和图片资源:
react-native bundle --entry-file index.android.js --bundle-output ./bundle/index.android.bundle --platform android --assets-dest ./bundle --dev false
--entry是入口js文件,android系统就是index.android.js,ios系统就是index.ios.js
--bundle-output就是生成的bundle文件路径
--platform是平台
--dev表示是否是开发版本,打正式版的安装包时我们将其赋值为false
打包成功后,如何控制RN加载Bundle的方式呢?没错,RN系统在ReactActivity下为我们提供了getJsBundleFile方法,在该方法中默认返回null,即加载assets下的bundle文件。我们可以根据条件来加载不同目录下的bundle文件即可。
我们将下载好的bundle文件到getFilesDir().getAbsolutePath()目录下,再次启动App时便会读取该目录下的bundle文件了,以后再有新版本的bundle文件,依然是下载覆盖掉这个bundle文件,到此,我们便完成了代码的热更新工作。