uniApp實(shí)現(xiàn)熱更新的思路與詳細(xì)過(guò)程
熱更新
熱更新是開(kāi)發(fā)中常見(jiàn)且常用的一種軟件版本控制的方式,在uniapp進(jìn)行使用熱更新將軟件實(shí)現(xiàn)更新操作
思路:
- 服務(wù)器中存儲(chǔ)著最新版本號(hào),前端進(jìn)行查詢
- 可以在首次進(jìn)入應(yīng)用時(shí)進(jìn)行請(qǐng)求版本號(hào)進(jìn)行一個(gè)匹對(duì)
- 如果版本號(hào)一致則不提示,反之則提示進(jìn)行更新執(zhí)行更新操作
實(shí)現(xiàn)
采用方法封裝進(jìn)行使用~
1.封裝一個(gè)對(duì)比版本號(hào)的函數(shù)
/**
* 對(duì)比版本號(hào),如需要,請(qǐng)自行修改判斷規(guī)則
* 支持比對(duì) ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1") ("3.0.0.1", "3.0") ("3.1.1", "3.1.1.1") 之類(lèi)的
* @param {Object} v1
* @param {Object} v2
* v1 > v2 return 1
* v1 < v2 return -1
* v1 == v2 return 0
*/
function compare(v1 = '0', v2 = '0') {
v1 = String(v1).split('.')
v2 = String(v2).split('.')
const minVersionLens = Math.min(v1.length, v2.length);
let result = 0;
for (let i = 0; i < minVersionLens; i++) {
const curV1 = Number(v1[i])
const curV2 = Number(v2[i])
if (curV1 > curV2) {
result = 1
break;
} else if (curV1 < curV2) {
result = -1
break;
}
}
if (result === 0 && (v1.length !== v2.length)) {
const v1BiggerThenv2 = v1.length > v2.length;
const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
for (let i = minVersionLens; i < maxLensVersion.length; i++) {
const curVersion = Number(maxLensVersion[i])
if (curVersion > 0) {
v1BiggerThenv2 ? result = 1 : result = -1
break;
}
}
}
return result;
}
2.封裝更新函數(shù)
通過(guò)
downloadTask.onProgressUpdate進(jìn)行監(jiān)聽(tīng),再通過(guò)plus.nativeUI.showWaiting("正在下載 - 0%");進(jìn)行加載顯示下載進(jìn)度…
var updateUseModal = (packageInfo) => {
const {
title, // 標(biāo)題
contents, // 升級(jí)內(nèi)容
is_mandatory, // 是否強(qiáng)制更新
url, // 安裝包下載地址
platform, // 安裝包平臺(tái)
type // 安裝包類(lèi)型
} = packageInfo;
let isWGT = type === 'wgt'
let isiOS = !isWGT ? platform.includes('iOS') : false;
let confirmText = isiOS ? '立即跳轉(zhuǎn)更新' : '立即下載更新'
return uni.showModal({
title,
content: contents,
showCancel: !is_mandatory,
confirmText,
success: res => {
if (res.cancel) return;
// 安裝包下載
if (isiOS) {
plus.runtime.openURL(url);
return;
}
let waiting = plus.nativeUI.showWaiting("正在下載 - 0%");
// uni.showLoading({
// title: '安裝包下載中'
// });
// wgt 和 安卓下載更新
const downloadTask = uni.downloadFile({
url,
success: res => {
if (res.statusCode !== 200) {
console.error('下載安裝包失敗', err);
return;
}
// 下載好直接安裝,下次啟動(dòng)生效
plus.runtime.install(res.tempFilePath, {
force: false
}, () => {
uni.hideLoading()
if (is_mandatory) {
//更新完重啟app
plus.runtime.restart();
return;
}
uni.showModal({
title: '安裝成功是否重啟?',
success: res => {
if (res.confirm) {
//更新完重啟app
plus.runtime.restart();
}
}
});
}, err => {
uni.hideLoading()
uni.showModal({
title: '更新失敗',
content: err.message,
showCancel: false
});
});
},
//接口調(diào)用結(jié)束
complete: ()=>{
uni.hideLoading();
downloadTask.offProgressUpdate();//取消監(jiān)聽(tīng)加載進(jìn)度
}
});
//監(jiān)聽(tīng)下載進(jìn)度
downloadTask.onProgressUpdate(res => {
// state.percent = res.progress;
waiting.setTitle("正在下載 - "+res.progress+"%");
// console.log('下載進(jìn)度百分比:' + res.progress); // 下載進(jìn)度百分比
// console.log('已經(jīng)下載的數(shù)據(jù)長(zhǎng)度:' + res.totalBytesWritten); // 已經(jīng)下載的數(shù)據(jù)長(zhǎng)度,單位 Bytes
// console.log('預(yù)期需要下載的數(shù)據(jù)總長(zhǎng)度:' + res.totalBytesExpectedToWrite); // 預(yù)期需要下載的數(shù)據(jù)總長(zhǎng)度,單位 Bytes
});
}
});
}
3.用變量接收實(shí)現(xiàn)函數(shù)(在函數(shù)中使用上方封裝的函數(shù))并導(dǎo)出
fRequestWithToken為我封裝的請(qǐng)求方法,可自行進(jìn)行使用axios進(jìn)行請(qǐng)求也行!!!
var fCheckVersion = (cb) => {
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {
// console.log(widgetInfo.version)
// console.log(plus.runtime.version)
// console.log(widgetInfo.version)
var nVerSta = compare(plus.runtime.version, widgetInfo.version),
sLaststVer = plus.runtime.version;
if (widgetInfo.version) {
if (nVerSta == 1) {
console.log(plus.runtime.version)
sLaststVer = plus.runtime.version
} else if (nVerSta == -1) {
console.log(widgetInfo.version)
sLaststVer = widgetInfo.version
}
}
console.log(sLaststVer)
//發(fā)送請(qǐng)求進(jìn)行匹對(duì),我這里數(shù)據(jù)庫(kù)設(shè)定的是如果返回null則版本號(hào)一致,反之需要更新!!!
fRequestWithToken({
ajaxOpts: {
url: URLS_COM.d_lastVer,
data: {
versionCode: sLaststVer
}
},
showloading: false,
silence:true
}).then(data => {
console.log(data)
// console.log('################')
if (data) {
var sUrl = '',
type = '';
if (data.wgtName) {
sUrl = data.wgtName;
type = "wgt"
} else {
sUrl = data.pkgName;
type = "pkg";
}
updateUseModal({
title: data.title||"",
contents: data.note||'',
is_mandatory: true,
url: sUrl,
platform: 'android',
type: type // 安裝包類(lèi)型
})
}
}).catch((res)=>{
cb&&cb()
console.log(res)
})
})
// #endif
}
export {
fCheckVersion
}
以上代碼即可實(shí)現(xiàn)熱更新的操作
使用
可在App.vue中進(jìn)行使用,根據(jù)項(xiàng)目需求而定
1.引入封裝好的函數(shù)
路徑自己記得填寫(xiě)自己封裝的位置
import{fCheckVersion} from '@/common/project/checkversion.js'
2.然后可以在onLoad函數(shù)中進(jìn)行觸發(fā)
onLoad() {
fCheckVersion();//檢查更新
}
這樣就實(shí)現(xiàn)了熱更新
然后的話只需要進(jìn)行打包個(gè)熱更新的包

后端進(jìn)行上傳至服務(wù)器進(jìn)行更新數(shù)據(jù)
本地再進(jìn)行一個(gè)云打包,記得在mainifest.json文件中進(jìn)行版本號(hào)的修改,修改成低于熱更新包的版本號(hào)即可

補(bǔ)充:uniapp整包升級(jí)
整包升級(jí)代碼:
在App.vue的onLaunch中,發(fā)起升級(jí)檢測(cè)請(qǐng)求,如下:
onLaunch: function () {
//#ifdef APP-PLUS
var server = "https://www.example.com/update"; //檢查更新地址
var req = { //升級(jí)檢測(cè)數(shù)據(jù)
"appid": plus.runtime.appid,
"version": plus.runtime.version
};
uni.request({
url: server,
data: req,
success: (res) => {
if (res.statusCode == 200 && res.data.status === 1) {
uni.showModal({ //提醒用戶更新
title: "更新提示",
content: res.data.note,
success: (res) => {
if (res.confirm) {
plus.runtime.openURL(res.data.url);
}
}
})
}
}
})
//#endif
}注意:App的升級(jí)檢測(cè)代碼必須使用條件編譯,否則在非App環(huán)境由于不存在plus相關(guān)API,將會(huì)報(bào)錯(cuò)。
升級(jí)地址URL,如果是自行托管的App,就提供自己的包地址。如果是打開(kāi)應(yīng)用市場(chǎng),那URL如下:
if (plus.os.name=="Android") {
appurl = "market://details?id=io.dcloud.hellouniapp"; //這個(gè)是通用應(yīng)用市場(chǎng),如果想指定某個(gè)應(yīng)用商店,需要單獨(dú)查這個(gè)應(yīng)用商店的包名或scheme及參數(shù)
}
else{
appurl = "itms-apps://itunes.apple.com/cn/app/hello-uni-app/id1417078253";
}總結(jié)
到此這篇關(guān)于uniApp實(shí)現(xiàn)熱更新的文章就介紹到這了,更多相關(guān)uniApp實(shí)現(xiàn)熱更新內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Javascript處理DOM元素事件實(shí)現(xiàn)代碼
DOM元素都有一些標(biāo)準(zhǔn)事件,一般使用時(shí)只要使用onclick=function的方式就可以了,但是當(dāng)需要為DOM元素添加多個(gè)事件,刪除事件,或在用Javascript封裝控件的時(shí)候,為封裝的控件添加自定義事件的時(shí)候2012-05-05
javascript異步編程代碼書(shū)寫(xiě)規(guī)范Promise學(xué)習(xí)筆記
這篇文章主要介紹了javascript異步編程代碼書(shū)寫(xiě)規(guī)范Promise學(xué)習(xí)筆記,需要的朋友可以參考下2015-02-02
JS實(shí)現(xiàn)預(yù)加載視頻音頻/視頻獲取截圖(返回canvas截圖)
這篇文章主要介紹了JS實(shí)現(xiàn)預(yù)加載視頻音頻/視頻獲取截圖(返回canvas截圖)的相關(guān)資料,需要的朋友可以參考下2017-10-10
JavaScript中的幾個(gè)關(guān)鍵概念的理解-原型鏈的構(gòu)建
JavaScript中的prototype,標(biāo)準(zhǔn)翻譯為“原型”,表示對(duì)象的初始形態(tài)2011-05-05
echarts圖形x、y坐標(biāo)文字設(shè)置間隔顯示及相關(guān)問(wèn)題詳解
最近在做一個(gè)web的數(shù)據(jù)統(tǒng)計(jì)部分用到了Echart,下面這篇文章主要給大家介紹了關(guān)于echarts圖形x、y坐標(biāo)文字設(shè)置間隔顯示及相關(guān)問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
JS判斷當(dāng)前是否平板安卓并是否支持cordova方法的示例代碼
這篇文章主要介紹了JS判斷當(dāng)前是否平板安卓并是否支持cordova方法,pc和安卓平板共用一套代碼,平板的代碼用了cordova做了一個(gè)殼子嵌套如果用了cordova就不支持elementUI中的上傳功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
JavaScript使用前綴樹(shù)(trie樹(shù))實(shí)現(xiàn)文本高亮
這篇文章主要為大家詳細(xì)介紹了JavaScript如何使用前綴樹(shù)(trie樹(shù))實(shí)現(xiàn)文本高亮效果,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下2024-04-04
js神秘的電報(bào)密碼 哈弗曼編碼實(shí)現(xiàn)
這篇文章主要介紹了js神秘的電報(bào)密碼 哈弗曼編碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09

