簡單說就是不須要去應用市場從新下載,直接打開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,後期也能夠多研究一下。