ReactNative 增量热更新思路

原创
2017/04/11 18:20
阅读数 265

增量热更新

ReactNative 增量更新

ReactNative 增量更新的内容包含 JS 和图片,在每次应用启动的时候请求服务器更新。
增量更新设计到版本号的管理,版本号存储位置有两个,一个是应用打包的只读目录,另一个是沙盒目录。

版本概念:

基线版本:

App 使用的最新的JS版本。 此 JS 版本号是初始化打包进 App 的,当 Native 代码升级的时候用户需要到市场升级。iOS 可以在 plist 文件加入一个Key 来存储。

当前版本:

JS 在 App 内每次在线更新升级到的版本号。

升级的思路是需要拿着本地的 JS 版本号,向服务器请求最新版本。

本地的 JS 版本号有以下几种状态:

  1. 第一次发布带有升级程序的 ReactNative 的App,“基线版本”为 0,“当前版本”为null,此时需要用“基线版本”号向服务器发送请求。
  2. 日常的 JS 升级,以”当前版本“号递增,从服务器获取最新版本。
  3. 需要发布到市场一次大版本,“当前版本” 例如为2.0,在打包的时候 “基线版本号” 一定是最大的,除非在发布新包的时候忘记升级 ”基线版本“,”基线版本“ 假如为3.0,JS 升级需要拿”基线版本“ 发送请求。为保险起见取 MAX(”基线版本“,"当前版本") 发送请求。

升级原理

JS增量

JS增量包生成使用BSDiff。
安卓和iOS使用BSPatch合并补丁,并导出合并方法给JS调用。

图片增量

图片升级使用git diff 命令找到上版本和当前版本中变化的图片,生成图片增量包。

原理是 ReactNative 会自动找打包命令生成的大 bundle 文件 所在的目录下的图片,所以只要保证我们全量图片和Bundle文件在一起,且严格按照以下的目录放置即可找到。

iOS图片必须有根目录 asset ,下面的图片按照模块文件名划分,asset和 bundle 文件是同级目录。。

安卓图片目录没有asset,四个文件夹 drawable-hdpi,drawable-mdpi,drawable-xhdpi,drawable-xxxhdpi 并列,和bundle文件是同级目录。

增量图片和JS补丁打成一个ZIP文件,下载到对应版本的目录后,首先把上个版本的图片和JS拷贝过来,然后解压,合并JS,覆盖图片。

最终实现的效果是:升级的每个版本都在沙盒中生成一个目录,包含 全量JS 全量图片,如果怕图片过多,可以只保留三个版本,每次升级把旧的版本删除。
回滚:如果升级后,程序启动闪退,且次数过多,需要执行自动回滚,沙盒中保存的历史版本就发挥作用了。只需要把当前版本号更改到上一个版本,让系统找到旧版本的main.jsbundle 就会回滚。

API设计

原生需要暴露给JS使用的类 XSYUpgradeManager
提供方法

  1. baseVersion 基线版本
  2. currentVersion 当前版本
  3. setVersion(version) 设置版本
  4. versionDesc(source,target) 版本比较,返回bool值
  5. combine(patchPath,newVersion,callback) bsdiff合并

其他相关类:

  1. XSYPatchCombine
combineIndexBundle
参数:
patchPath (String) 补丁目录
newVersion (String) 新版本号
completionHandler(combineResult)   合并之后的回调方法
  1. XSYJSVersion
setVersion 设置当前版本为升级后的版本
参数:
version (String) 新版本号
getBaseVersion 获取基线版本,意为打包时候的当前最新JS版本
getCurrentVersion 获取当前JS版本,用此方法得到的版本号请求服务器最新版本。
versionDesc 比较版本大小,返回BOOL
参数:
source(String)
target(String)
currentVersionBundleURL 获取当前JS版本的bundle路径
参数:
version(String)

JS代码更新

生成增量包

iOS:
react-native bundle --entry-file index.ios.js --bundle-output ./bundle/index.ios.jsbundle --platform ios --assets-dest ./bundle --dev false --minify true

Android:
react-native bundle --entry-file index.android.js --bundle-output ./bundle/index.android.jsbundle --platform android --assets-dest ./bundle --dev false

--entry-file 输入文件
--platform 平台语言
--dev 开发模式
--minify 压缩JS
--bundle-output 输出文件名

注意:如果Xcode直接运行打包,即便设置成--dev 为false
选择Release运行的时候Xcode 会自动执行此命令。

图片更新

1.服务器生成增量包
2.手机端下载增量包
3.手机端拷贝上版本所有图片到新版本目录
4.手机端合并增量图片为全量图片

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部