一、原理
- RN 打包后,会在 apk 或 ipa 中生成一个 jsBundle 文件,作为默认载入的文件,但同时预留了自定义 jsBundle 路径的接口,这也就给热更提供了基本的环境支持
android
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
....
@Override
protected String getJSBundleFile() {
return "JSBundlePath"
}
...
}
}
iOS
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return "JSBundlePath"
#endif
}
RN 同时提供了
react-native bundle
这样的命令来生成 jsBundle 文件,这样想办法自更新 JSBundlePath 文件就能实现热更了值得注意的是,这种热更只能更新动态文件,即 jsx 和 jsx 引用资源,对于需要包里面的其他模块,如原生模块是没有办法的
二、参考
以 react-native-pushy 为例子,只讲原理,不涉及代码
提供一个函数来计算 jsBundle,files 目录 > 默认目录,即默认目录作为 fallback
下载更新
以当前版本作为参数,请求服务器,返回
{
update: true,
name: '1.0.3-rc',
hash: 'hash',
description: '添加聊天功能\n修复商城页面BUG',
metaInfo: '{"silent":true}',
updateUrl: 'http://update-packages.reactnative.cn/hash',
pdiffUrl: 'http://update-packages.reactnative.cn/hash',
diffUrl: 'http://update-packages.reactnative.cn/hash',
}
根据返回的信息,下载新的 jsBundle 保存到 files 目录,这样就完成了热更
- 主要说一下 react-native-pushy 的增量更新功能,这是一个非常有用的功能,rn 的 jsBundle 哪怕只是一个 jsx 编译得到的,也有个 几百K, 稍微开发一下,可能就是 几M 了,根据实际情况,可能会更大。
react-native-pushy 实现增量更新的思路
diffUrl
最新版本 与 前一个版本的 增量,比如最新为 1.0.6, 用户当前的版本刚好为 1.0.5,那么就可以使用这个增量进行更新,即合并增量文件到 1.0.5 jsBundle 上作为 1.0.6 的 jsBundle
pdiffUrl
最新版本 与 初始版本的 增量,若当前用户安装后就没更新过,或者只更新到了 1.0.3,将增量合并到初始安装包 jsBundle 上 作为 1.0.6 的 jsBundle
updateUrl
完整的 1.0.6 文件,可全量下载,作为新的 jsBundle
最小化更新肯定是 diffUrl
,跨版本更新则使用相对于初始包的增量包 pdiffUrl
,其实也可以计算任意两个版本的增量,生成增量包,但这样,版本数量多的话,增量包就太多了。
react-native-pushy 使用了 bsdiff 作为增量更新工具,该工具提供了 bsdiff
和 bspatch
两个方法,使用 bsdiff
方法在服务端生成增量包,客户端下载增量包后,使用 bspatch
进行合并。