简单说就是不须要去应用市场从新下载,直接打开app就会下载更新的内容而后进入app,相似于常常玩游戏,游戏里须要更新,而后就有个进度条在读取。总结就是能够不经过应用市场来进行升级,极大的提高了app修bug和赋予新功能的能力前端
一个完整的RN-app程序一般包含如下几个部分:react
native代码部分android
js代码部分-rn代码、依赖的第三方库、业务代码等ios
图片资源部分react-native
若是你的项目的native代码发生了变更,对不起,热更新不能知足你的需求,你只能硬更新,让用户从新下载新的来覆盖旧的app。截止的当前日期,RN的版本还只是0.32,距离1.0还很遥远。因此常常会有须要用到的功能,而RN原生没有封装,因此只能亲自来写,固然,若是咱们有一个完整的无线团队,那么是极好的,直接去把无线团队里的类库中筛选个一些可能会用到的功能,先提早封装进来,尽可能的减小热更新的次数。app
而若是咱们是想修改图片资源或者是js的代码部分,好的,可使用热更新,那么既然是热更新,我就置想去修改变更的内容,计算方法:新版本(V3.1) - 旧版本(v3.0) = 增量包异步
好的,以上都是理论原理内容,因为项目期只有2我的在作RN前端方面的开发,因此没有足够的时间去开发公司内部的热更新。因此使用了第三方的组件react-native-pushy
ide
react-native-pushy
pushy函数
在工程target的Build Phases->Link Binary with Libraries中加入libz.tbd、libbz2.1.0.tbd测试
在你的AppDelegate.m文件中增长以下代码:
// ... 其它代码 #import "RCTHotUpdate.h" - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { #if DEBUG // 原来的jsCodeLocation jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; #else jsCodeLocation=[RCTHotUpdate bundleURL]; #endif // ... 其它代码 }
0.29及之后版本:在你的MainApplication中增长以下代码:
// ... 其它代码 import cn.reactnative.modules.update.UpdateContext; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override protected String getJSBundleFile() { return UpdateContext.getBundleUrl(MainApplication.this); } // ... 其它代码 } }
0.28及之前版本:在你的MainActivity中增长以下代码:
// ... 其它代码 import cn.reactnative.modules.update.UpdateContext; public class MainActivity extends ReactActivity { @Override protected String getJSBundleFile() { return UpdateContext.getBundleUrl(this); } // ... 其它代码 }
页面须要引用react-native-update模块
import { isFirstTime, isRolledBack, packageVersion, currentVersion, checkUpdate, downloadUpdate, switchVersion, switchVersionLater, markSuccess, } from 'react-native-update';
一般状况下,热更新的判断须要在app启动上来就要进行判断,那么大多数都会写在index.android.js中
componentWillMount(){ //去除debug时候的警告,测试的时候建议打开,hotloading的时候能够关掉 // console.disableYellowBox = true; // 2s 后若是尚未响应 则提示并取消 let freshedFlag = false; let timeout = setTimeout(() => { timeout && clearTimeout(timeout); if (freshedFlag) return; freshedFlag = true; console.log('超时'); //作些什么,好比setState让页面跳过 }, REQ_TIMEOUT); //防止反触发,就是更新完了回滚 markSuccess(); //异步函数checkUpdate能够检查当前版本是否须要更新 checkUpdate(appKey).then(info => { // freshedFlag 为 true 则说明超时 console.log('timeout'+freshedFlag); if (freshedFlag) { return; } else { freshedFlag = true; } //包过时,须要下载最新版的应用(非热更新) if (info.expired) { //进度条隐藏,新版本弹窗,提供下载地址 this.setState({ progressState:false, showDialog:true, downloadUrl:info.downloadUrl }) } //当前版本是最新版本,无需热更新 else if (info.upToDate) { this.setState({ progressState:false, progressNum: 100, welcome:false, update:false }) } else { //须要热更新了 this.doUpdate(info) } }).catch(err => { this.setState({ progressState:false, welcome:false, }) }); } //热更新函数 doUpdate = info => { //作点什么,让你的UI显示出来,提供个假性的进度条什么的 downloadUpdate(info).then(hash => { //下载完版本返回一个hash字符串,是当前笨笨的惟一标示,而后切换版本 switchVersion(hash); }).catch(err => { this.setState({ progressState:false, welcome:false, }) }); };
就理论而言,热更新操做到此结束,可是实际使用过程当中,5000个用户大概会有100个丢掉的可能性。不是特别的准,也存在少许用户回滚版本的行为。据说公司其余部门的团队作的app用的是codePush,后期也能够多研究一下。