这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
我们知道,在打包Android App之前,我们需要先通过HX生成打包资源。如果是通过cli创建的项目,则通过以下命令生成打包资源:
yarn build:app-plus
生成打包资源后的目录长这样:
然后将整个目录中的所有文件拷贝到Android项目的 assets/apps/<appid>/www
中:
可以看出,所有生成的文件,其实只是一个资源目录。
热更新的原理就是:替换资源目录中的所有打包资源
热更新包分析
我们通过HX生成的热更新包:
生成的热更新包长这样:
可以看出,wgt其实就是一个压缩文件,将生成的资源文件全部打包。
知道原理后,我们就不一定需要通过HX创建wgt了,我们可以使用yarn build:app-plus
命令先生成打包资源目录,再将其压缩为zip包,修改扩展名为wgt即可
注意:wgt包中,必须将manifest,json所在路径当做根节点进行打包。
打完包后,我们可以将其上传到OSS。
热更新方案
热更新方案:通过增加当前APP资源的版本号(versionCode),跟上一次打包时的APP资源版本号进行对比,如果比之前的资源版本号高,即进行热更新。
热更新原理:uniapp的热更新,其实是将build后的APP资源,打包为一个zip压缩包(扩展名改为wgt)。
涉及到的版本信息文件:
- src/manifest.json
- app.json (自己创建,用于版本对比)
- platforms/android/app/build.gradle
注意事项:
保证以上文件的versionName
和versionCode
均保持一致。
热更新核心代码
以下为热更新的核心代码:
// #ifdef APP-PLUS let downloadPath = "https://xxx.cn/apk/app.wgt" uni.downloadFile({ url: downloadPath, success: (downloadResult) => { if (downloadResult.statusCode === 200) { plus.runtime.install(downloadResult.tempFilePath, { force: true // 强制更新 }, function() { console.log('install success...'); plus.runtime.restart(); }, function(e) { console.error(e); console.error('install fail...'); }); } } }) // #endif
这里是下载wgt包,并进行安装的代码。以上代码无论如何都会下载wgt进行安装。
更新接口
实际上,在这之前,我们还需要判断是否需要更新,这就涉及到接口的部分。在此,只讲讲思路:
- 获取安装的版本名、版本号等信息,将其当做参数调用对应的更新接口;
- 接口取到这些信息,与最新版本进行对比,如果版本已经更新,返回需要更新的信息;
- 接口可以自行约定,怎么方便这么来。
我自己做的话,根本没写什么接口,只是创建了一个app.json
文件,用于存放最新版本信息:
{ "versionCode": "100", "versionName": "1.0.0" }
将其上传到OSS,然后在下载wgt包之前进行版本检查即可:
// #ifdef APP-PLUS plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) { console.log(widgetInfo); uni.request({ url: 'https://xxx.cn/apk/app.json', success: (result) => { let { versionCode, versionName } = result.data console.log({ versionCode, versionName }); // 判断版本名是否一致 if (versionName === widgetInfo.version) { // 如果安装的版本号小于最新发布的版本号,则进行更新 if (parseInt(widgetInfo.versionCode) < parseInt(versionCode)) { // 下载wgt更新包 let downloadPath = "https://xxx.cn/apk/app.wgt" uni.downloadFile({ url: downloadPath, success: (downloadResult) => { if (downloadResult.statusCode === 200) { plus.runtime.install(downloadResult.tempFilePath, { force: true // 强制更新 }, function() { console.log('热更新成功'); plus.runtime.restart(); }, function(e) { console.error('热更新失败,错误原因:' + e); }); } } }) } else { console.log('你的版本为最新,不需要热更新'); } } else { console.log('版本名不一致,请使用整包更新'); } } }); }); // #endif
OK,至此,热更新就完成了。
Android整包更新
看到上面更新逻辑,如果版本名不一致,则需要下载最新的apk进行安装,在下载之前,建议给用户一个更新提示:
console.log('版本名不一致,请使用整包更新'); let url = "https://xxx.cn/apk/app.apk" uni.showModal({ //提醒用户更新 title: "更新提示", content: "有新的更新可用,请升级", success: (res) => { if (res.confirm) { plus.runtime.openURL(url); } } })
以上代码是官方提供的,其实也可以下载apk成功后,直接调用install
进行安装:
console.log('版本名不一致,请使用整包更新'); let downloadPath = "https://zys201811.boringkiller.cn/shianonline/apk/app.apk" uni.showModal({ //提醒用户更新 title: "更新提示", content: "有新的更新可用,请升级", success: (res) => { if (res.confirm) { // plus.runtime.openURL(downloadPath)