第六章 如何打包RN項目 以及 熱更新的原理和應用

開發完了,該看看如何上線和維護一個項目了。

(一)打包apk

乍一看目錄結構,有一個Android的gradle項目,所以筆者瞬間就想到使用Android Studio生成一個簽名密鑰,然后打包生成正式簽名的apk,

(不太懂得給個鏈接自己去看:?http://blog.csdn.net/sunylat/article/details/9239595/

待筆者adb install這個apk以后才發現,日了,native的代碼跑完之后就紅屏了(Error),這才突然想到,在開發的時候貌似有這樣一個過程:

首次運行的話,有一個從服務端下載js的過程,所以中間肯定是缺了哪一步,才導致了無法訪問到我們的React native界面,

那么到底該如何打包這樣一個apk呢?

在這里詳解一下Android的,關于IOS的,想了解的自行去rn中文網

1)生成一個簽名密鑰,

①你可以像作者一樣用AS搞一個簽名文件放在桌面上~ ? 會生成一個

②也可以用命令行生成

因為作者不是這樣生成的,所以就不做介紹了,可以參考

http://reactnative.cn/docs/0.42/signed-apk-android.html#content

備注:這里一定要注意,記住你給密鑰起的別名(keyAlias),一定要記住,后面填錯了會報Failed to read key from keystore…

2)在gradle中配置上正式的簽名信息

別名要寫對,然后再buildTypes里弄上這一句,注意,名字要對應起來!寫的是config就是.config,至于下面的編譯時混淆的功能就不在這里進行詳細解釋了。

3)在Rn項目的android目錄中,執行./gradlew assembleRelease

前面的點別忘,記得要翻墻。(下載gradle過程中出現一堆點不要緊,只要保證網絡正常,過一會就會下載完成)。

Gradle的assembleRelease參數會把所有用到的JavaScript代碼都打包到一起,然后內置到APK包中。生成的APK文件位于android/app/build/outputs/apk/app-release.apk,它已經可以用來發布了。

4)可以用他提供的命令:./gradlew installRelease

也可以把apk直接adb install,這時候演示的時候已經可以脫離Reactpackager了

(二)熱更新方案 和 應用

1)什么是熱更新

? ? ? ?簡單說就是不需要去應用市場重新下載,直接打開app就會下載更新的內容然后進入app,類似于經常玩的手游,游戲里需要更新,然后就有個進度條在讀取。總結就是可以不通過應用市場來進行升級,極大的提升了app修bug和賦予新功能的能力。

備注:當然,Android現在app也可以在加載開機動畫的時候檢查更新,去服務端下載最新apk,然后調起install頁面安裝覆蓋。但體驗不佳,且IOS就無法這樣搞了…所以熱更新還是比較有研究價值的。

2)熱更新方案原理

就目前來看,RN的熱更新方案已有的,有微軟的CodePush和reactnative中文網的pushy。

從上面的圖中可以看出,當加載RN頁面的時候,需要先加載叫做JS bundle的文件,而加載bundle文件又有幾個途徑,通過對Android項目中native代碼的分析,可以得出bundle的加載路徑來源取決于JSBundleLoader的loadScript,而loadScript又調用了CatalystInstanceImpl的loadScriptFromAssets或者loadScriptFromFile,所以,加載bundle文件的途徑本質上有兩種方式:

①loadScriptFromAssets

從android項目下的assets文件夾下去加載,這也是RN發布版的默認加載方式,也就是在cmd命令行下使用gradlew assembleRelease命令打包簽名后的apk,里面的assets就包含有bundle文件

②loadScriptFromFile

第二種方式是從android文件系統也就是sd卡下去加載bundle。我們只要事先在sd卡下存放bundle文件,然后在ReactNativeHost的getJSBundleFile返回文件路徑即可。getJSBundleFile首先會嘗試在sd卡目錄下:data/data//cache/react_native/

看是否存在index.android.bundle文件,如果有,那么就會使用該bundle,如果沒有,那么就會返回null,這時候就是去加載assets下的bundle了。

具體的分析代碼過程可參考?http://blog.csdn.net/shandian000/article/details/54582603

所以,熱更新需要做的,就是兩點:

①把服務端存放的bundle patch(包括bundle文件和一些圖片資源)下載到sd卡

②在程序中加載bundle文件

根據bug的緊急/重要程度,可以把加載bundle的時機分為:立馬加載和下次啟動加載,這里將它們分別稱為熱加載和冷加載:

?(1)冷加載

冷加載方式比較簡單,不用做任何特殊處理,下載并解壓完patch.zip包之后,當應用完全退出之后(應用在后臺不算完全退出,應用被殺死才算),用戶再次啟動應用,就會去加載新的bundle了

?(2)熱加載

熱加載需要特殊處理一下,處理也很簡單,只要在解壓unzip之后,調用以下代碼即可

備注:這個檢測的過程也可以通過JS端調用Android Native提供的module來完成,具體請詳見前面的博客鏈接

3)熱更新的應用

熱更新可以自己搭服務進行,參考前面的博客鏈接,

但考慮到為了減少客戶端與服務端開發量起見,我們選用RN中文網上提供的pushy進行詳解

項目git地址: https://github.com/yujiesuperman/react-native-hotupload-thirdapp

① 去熱更新開放平臺注冊賬號,郵件激活 ??http://update.reactnative.cn

安裝 npm install -g react-native-update-cli rnpm

在Rn項目中:npm install --save react-native-update

rnpm link react-native-update 看到success

②配置Bundle URL,(這里提供Android的,Ios的請參考Rn中文網)

0.29及以后版本:在你的MainApplication中增加如下代碼:

即重寫getJSBundleFile方法。

③如果你之前沒安裝過NDK,你還必須安裝Android NDK,并設置環境變量ANDROID_NDK_HOME,指向你的NDK根目錄

④登錄與創建應用

pushy login

email:<輸入你的注冊郵箱>

password:<輸入你的密碼>

登錄之后可以創建應用。注意iOS平臺和安卓平臺需要分別創建:

$ pushy createApp --platform ios

App Name:<輸入應用名字>

$ pushy createApp --platform android

App Name:<輸入應用名字>

兩次輸入的名字可以相同,這沒有關系,create了以后,就可以看到update.json里的

備注:因為之前只創建了Android應用,所以只能看到Android相關信息

⑤接下來就該在應用里快速添加熱更新相關的代碼了

(1)先來看頭部的引入的組件

注釋里詳細介紹了每個組件的作用,以及獲取后面用到的參數appKey的方法

(2)然后看添加在thirdRNandNativeapp的主頁面內的方法

是的,眼尖的同學又發現了,除了兩個自定義的檢查更新和下載更新的方法外,又出現了一個生命周期內的函數:componentWillMount()。

在組件創建之前,會先調用getDefaultProps(),這是全局調用一次,嚴格地來說,這不是組件的生命周期的一部分。在組件被創建并加載的時候,首先調用getInitialState(),來初始化組件的狀態(現在多在構造里完成)。componentWillMount這個函數調用時機是在組件創建,并初始化了狀態之后,在第一次繪制render()之前。可以在這里做一些業務初始化操作,也可以設置組件狀態。這個函數在整個生命周期中只被調用一次。在這里我們進行了判斷是否是第一次啟動,或者是否模擬回滾操作。

(3)再來看頁面上添加的這一部分,render()函數里

在這一坨熱更新相關里,顯示了當前Native包的版本號packageVersion,

這個在Native代碼的這個位置:

熱更新下載下來的新的版本號currentVersion,如果沒有就顯示空。

備注:這時候運行,多半會遇到這個錯誤,

原因是有時候用rnpm去link代碼的時候會失敗,需要手動配置;

首先確認

這三個不要忘了添加,,作者就是忘了添加第三處。。教程里都沒有說。。。

然后在項目android目錄下的setting.gradle文件中添加

include ':react-native-update'

project(':react-native-update').projectDir =?

new File(rootProject.projectDir, '../node_modules/react-native-update/android')

然后在app目錄下的build.gradle文件中添加

dependencies {

compile project(':react-native-update') //<--這一句

……

}

運行實際效果圖:

因為這個時候服務端并沒有任何的版本,所以顯示

⑥發布應用

先重新打包一個代簽名的apk;方法見前。

pushy uploadApk android/app/build/outputs/apk/app-release.apk

即可上傳apk以供后續版本比對之用。

隨后你可以選擇往應用市場發布這個版本,也可以先往設備上直接安裝這個apk文件以進行測試。

這個時候上傳了版本后,再點擊更新,就顯示

注意:要在Rn目錄下執行這個命令,不能直接找到apk直接upload;要不然無法正常執行。

⑦修改一行代碼,然后上傳,

我們就把Demo1中的那張圖片加上,加完后效果:

⑧然后去命令行去發布新的版本

pushy bundle --platform android

版本名,版本描述,最后一個可以空著,然后綁定到一個版本上去,這時候再回到應用:

備注:可以看到,當我們下載更新完一個版本之后,首次啟動,isFirstTime會變為true,走那個模擬回滾的alert,在這里就不模擬了,感興趣的自己玩下~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容