共计 3465 个字符,预计需要花费 9 分钟才能阅读完成。
需要形容
如果想要做一个 app
的话,能够有很多种抉择计划,uni-app
是其中的一个性价比高一些(坑多一些)的计划。本文记录一下,uni-app
打 安卓包
当前,须要 查看并下载更新
,且 显示进度条
的性能。
代码在本人公司我的项目中利用,大家可放心使用。
需要:
- 查看版本是否是最新版
- 若不是最新版就下载远端服务器的最新的 apk 包
- 下载中须要显示下载了多少了,当下载到 100% 的时候,主动装置接口
思路剖析
比方咱们有一个设置页面,在设置页面中能够去进行版本更新。
1. 查看是不是最新版
当每次进入设置页面的时候,在 onShow 钩子
中向后端发申请,获取最新版本的信息,并与以后的版本信息做比照。
比方后端提供的有这样一个:获取最新版本信息 的接口
// 接口申请,返回数据如下:{
"code": 1,
"success": true,
"data": {
"id": 123456, // 存在数据库的 id
"applyName": "拼夕夕", // 版本名称
"applyVersion": "1.2.3", // 版本号
"versionDescribe": "此版本新增,是兄弟就帮忙砍一刀性能", // 版本形容
"fileSize":11566511, // 文件的总大小,计算下载进度百分比须要应用
"filePath": "http://ashuai.work:10000/appSrc/pdd.apk", // 版本的 url 门路,失常在浏览器地址栏中输出即间接下载了
... // 等等
},
"msg": "操作胜利"
}
咱们首先拿到后端返回的这个 applyVersion
字段的值 ”1.2.3″ 去和 当下的版本值
作比照
。如果远端的最新版的版本号高于当下的版本号,就阐明要更新了。否则当下的就是最新版,就不必更新。
那问题又来了,如何能拿到当下的版本呢?没关系,官网提供的有api
,能够间接获取的,代码如下:
plus.runtime.getProperty(plus.runtime.appid, (info) => {this.currentVersion = info.version; // 将当下版本存到 currentVersion 字段中去})
留神这个获取版本号的操作是异步的哦,异步,异步。
而后将版本号字符串 "a.b.c"
转换成 数字
进行比照即可。
形式有很多种,比方:a*100000 + b*1000 + c*1
// 当然这里须要
if(this.applyVersionVal > this.currentVersionVal){
// 须要更新
this.AndroidUpdate()}else {
// 以后已是最新版本
uni.showToast({
title: '以后已是最新版本',
duration: 2000,
icon:'none'
});
return
}
2. 更新下载服务器远端的 apk 文件 & 进度条显示
调用安卓的办法,创立一个下载工作,能拿到某一时刻下载的文件的大小,比照总大小即可失去下载进度百分比
AndroidCheckUpdate() {
const _this = this
uni.showModal({
title: "版本更新",
content: 'APP 有新版本公布,点击 立刻更新 进行最新版本下载。',
confirmText: '立刻更新',
cancelText: '稍后进行',
success: function(res) {if (res.confirm) {
_this.show = true // show 变量管制一个下载进度弹框(这个 UI 款式本人写即可)// 创立一个下载工作,并依据后端返回的 apk 动态资源地址 filePath 进行下载
var dtask = plus.downloader.createDownload(_this.filePath, {}, function(d, status) {
// 下载实现
if (status == 200) {
_this.show = false // 下载实现再把下载进度弹框敞开即可
plus.runtime.install(plus.io.convertLocalFileSystemURL(d
.filename), {}, {}, function(error) {
uni.showToast({
title: '装置失败',
duration: 1500
});
})
} else {
uni.showToast({
title: '更新失败',
duration: 1500
});
}
});
dtask.start(); // 下载工作开始下载
// 对于进度的获取是应用定时器一直获取曾经下载的文件的大小,再比照总大小即可
let timer = setInterval(() => {let percent = (dtask.downloadedSize / this.fileSize).toFixed(2) // fileSize 文件总大小,后端返回的
_this.percentVal = Math.floor(percent * 100) // 转成整数展现
if (percent >= 1) { // 留神百分比,及时革除定时器即可
clearInterval(timer)
}
}, 18)
} else if (res.cancel) {console.log('稍后更新');
}
}
});
}
进度条应用的是 u -popup 组件,如下:
<u-popup :round="10" :show="show" mode="center">
<view class="progressBox">
<u-loading-icon size="36"></u-loading-icon>
<text class="words"> 下载中 请勿退出 {{percentVal}}%</text>
</view>
</u-popup>
留神,下载这一块是要在手机模拟器上,能力看到成果哦。笔者工作中应用的是 逍遥模拟器,挺好。
因为
plus
变量在浏览器中是没有的
版本号
效果图
下载结束当前,安卓主动装置
为了不便大家去验证,笔者也提供了一个 apk 动态资源包 filePath: http://ashuai.work:10000/appSrc/pdd.apk
,在地址栏输出就能够拜访了。
动态资源 apk 接口
express
同级目录下,新建文件夹 app
寄存一下 apk
文件
// 先查问有没有这个 app,有的话返回这个动态 app 资源 url 地址
route.get('/findAppUrl', (req, res) => {res.header('Access-Control-Allow-Origin', '*');
let appName = (req.query.appName ? req.query.appName : 'pdd') + '.apk'
let files = fs.readdirSync('./app')
if (files.includes(appName)) { // 库存有
res.send({
code: '00000000',
url: "http://ashuai.work:10000/appSrc/" + appName
})
} else { // 库存没有
res.send({
code: '00000000',
url: ""
})
}
})
// 当拜访 app 资源时,就把对应的资源以流的模式返回去
route.get('/appSrc/:fileName', (req, res) => {res.header('Access-Control-Allow-Origin', '*');
let fileName = req.params.fileName // wms2month.apk
try {
// 存储一份 app 的门路
let appUrl = './app/' + fileName
let stat = fs.statSync(appUrl)
res.writeHead(200, {
'Content-Type': 'application/vnd.android.package-archive', // 安卓
'Content-Length': stat.size,
})
// 创立可读流
let readStream = fs.createReadStream(appUrl)
// 将读取的后果以管道 pipe 流的形式返回
readStream.pipe(res);
} catch (error) {res.send('暂无此 app 文件哦')
}
})
至于强制更新的话,就做一个判断即可,以后版本不是服务器远端的最新版本的话,就不让往下走,不让登录即可
好忘性不如烂笔头,记录一下吧 ^_^