乐趣区

关于uniapp:uniapp项目实践总结十九版本更新和热更新实现方法

导语:当一个 APP 利用开发实现当前,就要上架利用商店,但有时候批改一些小问题或者推出一些流动,又不想频繁地提交利用商店审核,那么就能够应用利用内更新性能来进行利用的版本升级更新或热更新,上面就介绍一下实现的办法。

目录

  • 筹备工作
  • 原理剖析
  • 实战演练
  • 案例展现

筹备工作

  • /pages/index 文件夹上面新建一个 version.vue 的组件;
  • 依照后面文章所说的页面构造,编写好预约的页面;

原理剖析

上面是利用更新的原理总结。

安装包版本更新

  • 通过 uni.getSystemInfoSync 办法的 appVersion 属性获取到利用以后安装包版本号;
  • 通过申请版本更新接口获取线上的安装包版本号;
  • 比拟两个安装包版本号的大小, 如果统一不更新, 如果不统一, 线上大于以后更新版本, 线上小于以后不更新;

资源包版本更新

  • 通过 uni.getStorage 获取本地资源包版本号, 如不存在, 则通过 uni.setStorage 设置默认版本号;
  • 通过申请版本更新接口获取线上的资源包版本号;
  • 比拟两个资源包版本号的大小, 如果统一不更新, 如果不统一, 线上大于以后更新版本, 线上小于以后不更新;

实战演练

模板应用

  • 比拟版本号
<view class="version-box">
  <view class="version-item">
    版本 1:
    <input
      class="version-item-ipt"
      type="text"
      placeholder="请输出版本 1"
      v-model="versionInfo.v1" />
  </view>
  <view class="version-item">
    版本 2:
    <input
      class="version-item-ipt"
      type="text"
      placeholder="请输出版本 2"
      v-model="versionInfo.v2" />
  </view>
  <view class="version-item">
    <button class="version-item-btn" type="primary" size="mini" @click="compareVersion('test')">
      比拟版本
    </button>
  </view>
  <view class="version-item" v-show="versionInfo.text">
    <text> 比拟后果:</text>
    <text class="version-item-txt">{{versionInfo.text}}</text>
  </view>
</view>
  • 获取线上版本
<!-- #ifdef APP-PLUS -->
<view class="version-box">
  <view class="version-item">
    <button class="version-item-btn" type="primary" size="mini" @click="getVersion">
      获取版本
    </button>
  </view>
  <view class="version-item"> 以后版本: {{checkInfo.current}} </view>
  <view class="version-item"> 线上版本: {{checkInfo.online}} </view>
  <view class="version-item"> 以后资源包版本: {{checkInfo.currentSource}} </view>
  <view class="version-item"> 线上资源包版本: {{checkInfo.onlineSource}} </view>
</view>
<!-- #endif -->
  • 检测更新
<!-- #ifdef APP-PLUS -->
<view class="version-box">
  <view class="version-item">
    <button class="version-item-btn" type="primary" size="mini" @click="checkUpdate">
      检测更新
    </button>
  </view>
  <view class="version-item" v-show="checkInfo.showProgress">
    <progress
      :percent="checkInfo.currentProgress"
      show-info
      :stroke-width="8"
      active-color="#24afd6" />
  </view>
</view>
<!-- #endif -->

款式编写

.version-box {
  padding: 10rpx;
  .version-item {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    margin-bottom: 20rpx;
    padding: 0 10rpx;
    .version-item-ipt {
      margin-left: 20rpx;
      padding: 10rpx;
      border: 3rpx solid $e;
      font-size: 27rpx;
    }
    .version-item-btn {margin: 0;}
    .version-item-txt {color: $mainColor;}
    .uni-progress {width: 100%;}
  }
}

脚本应用

定义数据

  • 比拟版本信息
const versionInfo = reactive({
  v1: "", // 版本 1
  v2: "", // 版本 2
  text: "", // 检测后果
});
  • 检测版本信息
const checkInfo = reactive({
  current: "0.0.0", // 以后版本
  online: "0.0.0", // 线上版本
  currentSource: 0, // 以后资源包
  onlineSource: 0, // 线上资源包
  result: "", // 检测后果
  data: null, // 在线信息
  type: "", // 装置类型
  showProgress: false, // 显示进度条
  currentProgress: 0, // 以后进度
  downloader: null, // 下载定时器
});

办法调用

  • 模仿版本更新数据

应用之前介绍的动态服务器搁置版本更新配置文件,格局如下:

{
  "install": {
    "version": "1.0.0",
    "des": "敬爱的用户:\n 有新的安装包公布了 \n 是否更新?",
    "url": "http://192.168.1.11:3000/xxx-1.0.0.apk"
  },
  "source": {
    "version": 1,
    "des": "敬爱的用户:\n 有新的资源包公布了 \n 是否更新?",
    "url": "http://192.168.1.11:3000/xxx-001.wgt"
  }
}
  • 比拟版本号封装办法
// scripts/utils.js
// 比拟版本号
function compareVersion(v1, v2) {v1 = v1.split(".");
  v2 = v2.split(".");
  let len = Math.max(v1.length, v2.length);
  while (v1.length < len) {v1.push("0");
  }
  while (v2.length < len) {v2.push("0");
  }

  for (let i = 0; i < len; i++) {let num1 = parseInt(v1[i]),
      num2 = parseInt(v2[i]);

    if (num1 > num2) {return 1;} else if (num1 < num2) {return -1;}
  }

  return 0;
}
  • 比拟版本操作
function compareVersion() {if (versionInfo.v1 == "") {
    uni.showToast({
      title: "请输出版本 1!",
      icon: "error",
    });
    return;
  }
  if (versionInfo.v2 == "") {
    uni.showToast({
      title: "请输出版本 2!",
      icon: "error",
    });
    return;
  }
  let res = proxy.$apis.utils.compareVersion(versionInfo.v1, versionInfo.v2);
  switch (res) {
    case 0:
      versionInfo.text = "版本 1 和版本 2 雷同!";
      break;
    case 1:
      versionInfo.text = "版本 1 比版本 2 要新!";
      break;
    case -1:
      versionInfo.text = "版本 1 比版本 2 要老!";
      break;
    default:
      break;
  }
}
  • 获取在线版本操作
async function getVersion() {let system = uni.getSystemInfoSync();
  let opts = {
    url: proxy.$apis.urls.version,
    method: "get",
  };
  let data = await proxy.$http.request(opts),
    v1 = system.appVersion,
    v2 = data.install.version;
  versionInfo.v1 = v1;
  versionInfo.v2 = v2;
  checkInfo.current = v1;
  checkInfo.online = v2;
  checkInfo.data = data;
  getSource();
  console.log("申请后果:", data);
}
  • 检测更新办法
function checkUpdate() {let result = proxy.$apis.utils.compareVersion(checkInfo.current, checkInfo.online);
  checkInfo.result = result;
  // 本地版本最新
  if (checkInfo.result == 1) {
    uni.showToast({
      title: "已是最新版本!",
      icon: "success",
    });
    return;
  }
  // 线上版本最新
  if (checkInfo.result == -1) {let { des, url} = checkInfo.data.install;
    checkInfo.type = "install";
    installSet(des, url);
  }
  // 本地和线上版本雷同
  if (checkInfo.result == 0) {checkSource();
  }
}
  • 获取资源包版本
//
async function getSource() {let { source} = checkInfo.data,
    v1 = 0,
    v2 = 0,
    local = await proxy.$apis.utils.storeage({
      type: "get",
      isSync: true,
      key: "source",
    });
  if (local.code == 1) {v1 = local.data;} else {
    proxy.$apis.utils.storeage({
      type: "set",
      isSync: true,
      key: "source",
      val: 0,
    });
    v1 = 0;
  }
  let {version} = source;
  v2 = version;
  checkInfo.currentSource = v1;
  checkInfo.onlineSource = v2;
}
  • 资源包版本检测
function checkSource() {if (checkInfo.currentSource >= checkInfo.onlineSource) {
    uni.showToast({
      title: "已是最新版本!",
      icon: "success",
    });
    return;
  }
  let {des, url} = checkInfo.data.source;
  checkInfo.type = "source";
  installSet(des, url);
}
  • 文件安装操作
function installSet(content, url) {
  uni.showModal({
    title: "零碎音讯",
    content,
    cancelText: "勾销更新",
    cancelColor: "#333",
    confirmText: "立马更新",
    confirmColor: "#24afd6",
    success(res) {if (res.confirm) {downloadFile(url);
      }
    },
    fail() {
      uni.showToast({
        title: "更新失败!",
        icon: "error",
      });
    },
  });
}
  • 下载文件操作
async function downloadFile(url) {
  checkInfo.showProgress = true;
  downloadTime();
  let opts = {url,};
  let data = await proxy.$http.download(opts);
  if (data.code === 103) {
    checkInfo.showProgress = false;
    checkInfo.currentProgress = 0;
    uni.showToast({
      title: "下载失败!",
      icon: "error",
    });
    return;
  }
  if (data) {
    checkInfo.currentProgress = 100;
    installFile(data);
  }
}
  • 下载定时器
function downloadTime() {checkInfo.downloader = setInterval(() => {if (checkInfo.currentProgress < 90) {let randomNum = Math.ceil(Math.random() * 5);
      checkInfo.currentProgress += randomNum;
    } else {clearInterval(checkInfo.downloader);
    }
  }, 1000);
}
  • 装置下载的文件
function installFile(file) {if (plus) {
    uni.showLoading({title: "文件装置中...",});
    plus.runtime.install(
      file,
      {force: true,},
      (res) => {uni.hideLoading();
        checkInfo.showProgress = false;
        checkInfo.currentProgress = 0;
        proxy.$apis.utils.storeage({
          type: "set",
          isSync: true,
          key: "source",
          val: checkInfo.data.source.version,
        });
        plus.runtime.restart();},
      (err) => {uni.hideLoading();
        checkInfo.showProgress = false;
        checkInfo.currentProgress = 0;
        uni.showToast({
          title: "装置失败!",
          icon: "error",
        });
      }
    );
  } else {
    uni.showToast({
      title: "此版本不反对!",
      icon: "error",
    });
  }
}

微信小程序更新

依据微信小程序官网的文档,更新办法如下:

微信小程序检测更新文档

const updateManager = wx.getUpdateManager();

updateManager.onCheckForUpdate(function (res) {
  // 申请完新版本信息的回调
  console.log(res.hasUpdate);
});

updateManager.onUpdateReady(function () {
  wx.showModal({
    title: "更新提醒",
    content: "新版本曾经筹备好,是否重启利用?",
    success: function (res) {if (res.confirm) {
        // 新的版本曾经下载好,调用 applyUpdate 利用新版本并重启
        updateManager.applyUpdate();}
    },
  });
});

updateManager.onUpdateFailed(function () {// 新版本下载失败});

案例展现

h5 端成果

  • 比拟版本办法示例

APP 端成果

  • 已是最新版本
  • 安装包新版本更新
  • 资源包新版本更新

最初

以上就是版本更新和热更新实现办法的次要内容,有不足之处,请多多斧正。

退出移动版