androidapp整包更新,uniapp热更新和整包更新
[TOC]
# uniapp热更新和整包更新
我们知道,在打包Android App之前,我们需要先通过HX⽣成打包资源。如果是通过cli创建的项⽬,则通过以下命令⽣成打包资源:
```
yarn build:app-plus
```
⽣成打包资源后的⽬录长这样:
然后将整个⽬录中的所有⽂件拷贝到Android项⽬的 `assets/apps//www` 中:
可以看出,所有⽣成的⽂件,其实只是⼀个资源⽬录。
热更新的原理就是:**替换资源⽬录中的所有打包资源**
## 热更新包分析
我们通过HX⽣成的热更新包:
⽣成的热更新包长这样:
可以看出,wgt其实就是⼀个压缩⽂件,将⽣成的资源⽂件全部打包。
知道原理后,我们就不⼀定需要通过HX创建wgt了,我们可以使⽤`yarn build:app-plus`命令先⽣成打包资源⽬录,再将其压缩为zip包,修改扩展名为wgt即可:
注意到我两次都将`manifest.json`圈红,⽬的是强调:**wgt包中,必须将manifest,json所在路径当做根节点进⾏打包**。
打完包后,我们可以将其上传到OSS。
## 热更新⽅案
热更新⽅案:通过增加当前APP资源的版本号(versionCode),跟上⼀次打包时的APP资源版本号进⾏对⽐,如果⽐之前的资源版本号⾼,即进⾏热更新。
热更新原理:uniapp的热更新,其实是将build后的APP资源,打包为⼀个zip压缩包(扩展名改为wgt)。
涉及到的版本信息⽂件:
- src/manifest.json
- app.json (⾃⼰创建,⽤于版本对⽐)
- platforms/android/adle
注意事项:
保证以上⽂件的`versionName`和`versionCode`均保持⼀致。
## 热更新核⼼代码
以下为热更新的核⼼代码:
```js
// #ifdef APP-PLUS
let downloadPath = "xxx/apk/app.wgt"
uni.downloadFile({
url: downloadPath,
success: (downloadResult) => {
if (downloadResult.statusCode === 200) {
plus.runtime.pFilePath, {
force: true // 强制更新
}, function() {
console.log('');
start();
}, function(e) {
<(e);
<('');
});
}
}
})
// #endif
```
这⾥是下载wgt包,并进⾏安装的代码。以上代码⽆论如何都会下载wgt进⾏安装。
## 更新接⼝
实际上,在这之前,我们还需要判断是否需要更新,这就涉及到接⼝的部分。在此,只讲讲思路:
1. 获取安装的版本名、版本号等信息,将其当做参数调⽤对应的更新接⼝;
2. 接⼝取到这些信息,与最新版本进⾏对⽐,如果版本已经更新,返回需要更新的信息;
3. 接⼝可以⾃⾏约定,怎么⽅便这么来。
我⾃⼰做的话,根本没写什么接⼝,只是创建了⼀个`app.json`⽂件,⽤于存放最新版本信息:```json
android最新版{
"versionCode": "100",
"versionName": "1.0.0"
}
```
将其上传到OSS,然后在下载wgt包之前进⾏版本检查即可:
```js
/
/ #ifdef APP-PLUS
Property(plus.runtime.appid, function(widgetInfo) { console.log(widgetInfo);
url: 'xxx/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 = "xxx/apk/app.wgt"
uni.downloadFile({
url: downloadPath,
success: (downloadResult) => {
if (downloadResult.statusCode === 200) {
plus.runtime.pFilePath, {
force: true // 强制更新
}, function() {
console.log('热更新成功');
start();
}, function(e) {
<('热更新失败,错误原因:' + e);
});
}
}
})
} else {
console.log('你的版本为最新,不需要热更新');
}
} else {
console.log('版本名不⼀致,请使⽤整包更新');
}
}
});
});
// #endif
```
OK,⾄此,热更新就完成了。
## Android整包更新
看到上⾯更新逻辑,如果版本名不⼀致,则需要下载最新的apk进⾏安装,在下载之前,建议给⽤户⼀个更新提⽰:```js
console.log('版本名不⼀致,请使⽤整包更新');
let url = "xxx/apk/app.apk"
uni.showModal({ //提醒⽤户更新
title: "更新提⽰",
content: "有新的更新可⽤,请升级",
success: (res) => {
if (firm) {
plus.runtime.openURL(url);
}
}
})
```
以上代码是官⽅提供的,其实也可以下载apk成功后,直接调⽤`install`进⾏安装:
```js
console.log('版本名不⼀致,请使⽤整包更新');
let downloadPath = "zys201811.boringkiller/shianonline/apk/app.apk"
uni.showModal({ //提醒⽤户更新
title: "更新提⽰",
content: "有新的更新可⽤,请升级",
success: (res) => {
if (firm) {
// plus.runtime.openURL(downloadPath);
uni.downloadFile({
url: downloadPath,
success: (downloadResult) => {
if (downloadResult.statusCode === 200) {
console.log('正在更新...');
plus.runtime.pFilePath, {
force: true // 强制更新
}, function() {
console.log('整包更新成功');
start();
}, function(e) {
<('整包更新失败,错误原因:' + e);
});
}
}
})
}
}
})
```
## 热更新的⾃动化处理
知道原理后,就好办了,我们可以将其繁杂的⼯作⾃动化,以减少重复劳动。
修改`package.json`的相关打包脚本:
```json
{
"name": "shianaonline",
"version": "0.1.224",
"private": true,
"scripts": {
"apk": "node deploy/scripts/build-apk.js",
"wgt": "node deploy/scripts/build-wgt.js",
"build:app-plus-android": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus
UNI_OUTPUT_DIR=./platforms/android/app/src/main/assets/apps/your appid/www vue-cli-service uni-build",
"build:app-plus-ios": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus
UNI_OUTPUT_DIR=./platforms/iOS/apps/your appid/www vue-cli-service uni-build",
}
}
```