當一個 APP在運行的時候, 開發者想要將本身的代碼更新到用戶的手機上時, 通常都有兩種方案, 一是熱更新, 二就是 APP 更新.
熱更新暫且不說,這篇文章就講講 APP 如何更新react
versionCode
, versionCodeSwitch
, notUpdate
, deleteApp
versionCode
經過 code 來升級版本,通常是一個數字(在 ios 裏提交 App Store 的時候有須要用到的地方), 這樣 versionName
並不會增長, 可是若是添加了 versionCode
, 若是要升級 versionName
, versionCode
也須要增長versionCodeSwitch
用來控制是否要根據versionCode
來更新, 通常我都是在測試和其餘環境開啓,生產環境關閉的notUpdate
是否要根據遠程信息來更新, 通常都是開啓狀態deleteApp
安卓 app 須要卸載從新安裝, 由於直接安裝可能存在某些問題, 將會使用此信息,先刪除 APP, 再從新下載react-native-device-info
這個庫, 這個庫裏面提供的信息較全, 固然也可使用原生方法, 來獲取APP的信息versionName
比較方案, 較爲簡陋:/** * 比較兩版本號 * @param currentVersion * @return boolean * true=須要更新 false=不須要 */ compareVersion = (currentVersion: string): boolean => { const {versionName: remoteVersion} = this.remoteInfo || {} if (!remoteVersion) { return false } if (currentVersion === remoteVersion) { return false } const currentVersionArr = currentVersion.split('.') const remoteVersionArr = remoteVersion.split('.') for (let i = 0; i < 3; i++) { if (Number(currentVersionArr[i]) < Number(remoteVersionArr[i])) { return true } } return false }
@ReactMethod public void installApk(String filePath, String fileProviderAuthority) { File file = new File(filePath); if (!file.exists()) { Log.e("RNUpdater", "installApk: file doe snot exist '" + filePath + "'"); // FIXME this should take a promise and fail it return; } if (Build.VERSION.SDK_INT >= 24) { // API24 and up has a package installer that can handle FileProvider content:// URIs Uri contentUri; try { contentUri = FileProvider.getUriForFile(getReactApplicationContext(), fileProviderAuthority, file); } catch (Exception e) { // FIXME should be a Promise.reject really Log.e("RNUpdater", "installApk exception with authority name '" + fileProviderAuthority + "'", e); throw e; } Intent installApp = new Intent(Intent.ACTION_INSTALL_PACKAGE); installApp.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); installApp.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); installApp.setData(contentUri); installApp.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, reactContext.getApplicationInfo().packageName); reactContext.startActivity(installApp); } else { // Old APIs do not handle content:// URIs, so use an old file:// style String cmd = "chmod 777 " + file; try { Runtime.getRuntime().exec(cmd); } catch (Exception e) { e.printStackTrace(); } Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.parse("file://" + file), "application/vnd.android.package-archive"); reactContext.startActivity(intent); } }若是是咱們本身提供下載服務,須要注意的是帶寬, 若是網速過慢則用戶體驗過差, 還有就會帶來更多的流量消耗, 其中的取捨,須要開發者決定
在打包時, 經過腳本更新接口或者文件信息, 固然這個得看具體的打包方案
好比我如今的方案是使用 Jenkins 打包, 在打包時使用 shell 腳本更新對應信息(有須要也可使用其餘語言腳本):android
androidVersionFilePath="$WORKSPACE/android/app/build.gradle" // 經過此文件獲取安卓的版本信息 iosVersionFilePath="$WORKSPACE/ios/veronica/Info.plist" // 經過此文件獲取iOS的版本信息 changeLogPath="$WORKSPACE/change.log" // 將版本更新信息存儲在此文件中
getAndroidVersion(){ androidVersion=$(cat $androidVersionFilePath | grep "versionName" | awk '{print $2}' | sed 's/\"//g') androidCode=$(cat $androidVersionFilePath | grep "versionCode " | awk '{print $2}' | sed 's/\"//g') androidDelete=$(cat $androidVersionFilePath | grep "deleteApp" | awk '{print $4}' | sed 's/\"//g') return 0 } getIOSVersion(){ rows=$(awk '/CFBundleShortVersionString/ {getline; print}' $iosVersionFilePath) iosVersion=$(echo "$rows" | sed -ne 's/<string>\(.*\)<\/string>/\1/p') iosVersion=$(echo "$iosVersion" | sed 's/^[[:space:]]*//') rows2=$(awk '/VersionCode/ {getline; print}' $iosVersionFilePath) iosCode=$(echo "$rows2" | sed -ne 's/<string>\(.*\)<\/string>/\1/p') iosCode=$(echo "$iosCode" | sed 's/^[[:space:]]*//') return 0 } desc=$(cat $changeLogPath | tr "\n" "#")
sed -i '' "s/\"releaseInfo\":.*$/\"releaseInfo\": \"$desc\"/" $JsonPath/$fileName sed -i '' "s/\"versionName\":.*$/\"versionName\": \"$versionName\",/" $JsonPath/$fileName sed -i '' "s/\"versionCode\":.*$/\"versionCode\": \"$versionCode\",/" $JsonPath/$fileName sed -i '' "s/\"deleteApp\":.*$/\"deleteApp\": \"$deleteApp\",/" $JsonPath/$fileName個人文件是以 json 做爲格式的,說明文字是能夠任意填寫的,會觸發一些解析問題:
JSON.parse
解析失敗的符號, 如 \ , ````, \n
,\r
, \"
等等#
切割的, 因此也不容許出現這個符號關於 APP 原生版本的更新流程基本就是這樣,固然這個流程不光適用 APP, 也能夠用於 PC 軟件的更新
除了原生版本的更新,還有熱更新, 也是很是重要的, 我將會在後面的博客中解析他ios
完shell