react-native热更新集成(使用CodePush)
终于要集成下rn的热更新了,这边挑选了微软的CodePush服务https://microsoft.github.io/code-push/
首先列一下大体步骤:
- 本地安装CodePush cli
- 注册CodePush账号
- 把要接入的项目加入到你的CodePush中
- 项目中安装CodePush sdk
- 加入集成的代码
- 发布更新版本来测试
上面的1 2 3步骤下面各种教程都有,就只粗略写一下,重点写具体项目集成的
1、2 安装注册
本地安装CodePush cli:
|
|
注册账号:
|
|
如果直接在官网注册了,输入这个会弹出来token,复制到命令行就ok了
3 把要接入的项目加入到你的CodePush中
要把项目的安卓和ios都分别添加进去
|
|
每个app添加的时候,都会输出它的deployment key的表格,Staging和Production,复制下来备用。可以测试用Staging,线上用Production,用哪个都行,后面集成的时候对应好可以。
添加完可以用下面命令查看你添加了哪些app(官网上登录了也可以看到):
|
|
4 在项目中安装CodePush sdk
首先安装和link,和别的插件步骤一样
|
|
link的时候,会提示让你输入deploymentKey,这个key就是上面添加app后输出的那个表格,选你要的环境的key就好(比如用Staging的话,安卓、ios都输入Staging的key)
link好了之后去看下两个地方:
ios的info.plist中CodePushDeploymentKey有没有成功加进去,没有就自己手加下
android里android/app/src/main/java/com/…(你app的名字)/MainApplication.java这文件
123456789101112131415161718192021222324252627282930313233//...(各种引入太长了省略)//新添加的import com.microsoft.codepush.react.CodePush;//...(各种引入太长了省略)public class MainApplication extends NavigationApplication {//新添加的这个getJSBundleFile重写public String getJSBundleFile(){return CodePush.getJSBundleFile();}public boolean isDebug() {return BuildConfig.DEBUG;}protected List<ReactPackage> getPackages() {return Arrays.<ReactPackage>asList(new RNCameraPackage(),new SplashScreenReactPackage(),new RNVersionNumberPackage(),//新添加的new CodePush("h42yJwZPRwunc2KwitUiHZxvNHrda7eba4ac-fdd0-4f23-8f78-1b82ff7d5664",getApplicationContext(),BuildConfig.DEBUG));}public List<ReactPackage> createAdditionalReactPackages() {return getPackages();}public String getJSMainModuleName() {return "index";}}
5 集成
(这块我也不是很确定我这样的思路是不是正确的,没有去找教程之类的参考,所以如果有问题或者有更好的解决方式,麻烦指教下~)
首先在App的外面用codepush包起来,配置为手动更新。checkFrequency可以设置更新的方式,如果是自动的话就会自己检测然后下载,静默的,我这边的需求是要提示页面的所以走手动。
|
|
首先我项目中用了react-native-navigation,所以为了拎出来做这块就把热更新的承载页面也作为一个root route。在注册玩所有route后,先检查一下有没有更新版本,有就先render到热更新承载页,再进入具体的更新相关的操作。
|
|
检测到有更新包就进入hot这个root,这块儿就处理我们更新相关的逻辑,比如显示下载的进度,成功与否的提示之类的。checkForUpdate和sync这两个api可以详细看文档的解释,checkForUpdate是一个promise,返回了新包的相关参数,sync是触发更新的操作、可以监听整个流程。
|
|
6 发布更新
可以使用release-react这个简化命令发布更新代替使用release,但是所有的参数也是可以配置的,可以仔细读一下文档https://github.com/Microsoft/code-push/tree/master/cli#releasing-updates-react-native 对每个参数都有解释
|
|
我项目里最后发布的命令如下是这样的,由于我使用的Production key,所以这边deploymentName也换成Production,默认是Staging,targetBinaryVersion不传的话默认会去android/gradle.properties下读,你的文件里没有的话就在命令里自己传进去。
|
|
CodePush.checkForUpdate()会检测对应当前版本的热更新包,比如你本地是1.0.3的包,传的是1.0.2的热更新包,.3是不会检测到这个更新的。更新包的时候可以打各种方式的版本,1.x.x之类的,可以细看文档描述。
发布后可以看下所有发布了包历史:
|
|
会显示有多少个client安装了更新包
清除更新包:
|
|
碰到的问题
测试的时候发现,下载好更新包后马上更新的内容是最新的,但是重启app的时候就自动rollback了,但是sync时却返回state为0,已经是最新的包了。后来在issue里找到类似的问题https://github.com/microsoft/react-native-code-push/issues/1564 。在最外面一层加上CodePush.notifyAppReady(),通知一下。
文档里是这样写notifyAppReady这个api的:
Notifies the CodePush runtime that an installed update is considered successful. If you are manually checking for and installing updates (i.e. not using the sync method to handle it all for you), then this method MUST be called; otherwise CodePush will treat the update as failed and rollback to the previous version when the app next restarts.
虽然我们这边是使用的sync,按他的说法应该sync会自动做好这件事情,但是显然没有到达预期,所以手动加一下,重新测试发现的确解决了这个问题。
|
|
参考
官网:https://microsoft.github.io/code-push/
CodePush client sdk文档:https://docs.microsoft.com/en-us/appcenter/distribution/codepush/react-native
各种别人的教程、经验分享:
https://blog.csdn.net/w178191520/article/details/86361785
http://techblog.sishuxuefu.com/atricle.html?5beaa7e59f5454007039e01c
https://www.jianshu.com/p/6a5e00d22723
https://github.com/microsoft/react-native-code-push/issues/1564