您好,登錄后才能下訂單哦!
這篇文章主要介紹了React原生APP更新的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
1.在 App 打開時請求接口或文件, 獲取遠程版本/版本更新說明/地址等等重用信息
2.通過庫或者原生方案, 獲取 App 的當前版本
3.比較遠程版本和當前版本的區別(可以使用庫,也可以自己寫一個比較方案)
4.通過獲取到的鏈接進行操作(可以跳轉到對應網站下載,類似蒲公英這種,可以是 apk 鏈接, 通過安卓原生方法下載, 也可以是 App Store 鏈接)
詳細說明:
1.這些遠程信息,可以是接口, 這樣可以有一個中臺來控制, 當然也可以是一個文件, 讓運維來控制
關于信息,不止于遠程版本, 在項目里還可以添加其他屬性,如: versionCode, versionCodeSwitch , notUpdate , deleteApp
1.1 versionCode 通過 code 來升級版本,一般是一個數字(在 ios 里提交 App Store 的時候有需要用到的地方), 這樣 versionName 并不會增加, 但是如果添加了 versionCode, 如果要升級 versionName, versionCode 也需要增加
1.2 versionCodeSwitch 用來控制是否要根據versionCode來更新, 一般我都是在測試和其他環境開啟,生產環境關閉的
1.3 notUpdate 是否要根據遠程信息來更新, 一般都是開啟狀態
1.4 deleteApp 安卓 app 需要卸載重新安裝, 因為直接安裝可能存在某些問題, 將會使用此信息,先刪除 APP, 再重新下載
2.獲取當前手機的信息,方案較多, 我使用的是 react-native-device-info 這個庫, 這個庫里面提供的信息較全, 當然也可以使用原生方法, 來獲取APP的信息
3.關于本地版本號和原生版本號之間的對比也是可以使用庫,也可以自己寫, 這邊推薦兩個庫,下載量都是百萬以上的: semver-compare 和 compare-versions, 這邊附上我的 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 }
關于下載 app 有很多方案, 最簡單的就是跳轉鏈接到第三方平臺, 像蒲公英這樣的, 使用 RN 提供的 Linking 方法來直接跳轉
當然安卓是可以直接通過自己提供的地址下載的, 這里提供一個方法(此方法來源于網絡):
@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 腳本更新對應信息(有需要也可以使用其他語言腳本):
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, \" 等等
因為說明文字的換行我是通過 # 切割的, 所以也不允許出現這個符號
感謝你能夠認真閱讀完這篇文章,希望小編分享的“React原生APP更新的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。