最近公司小程序的需求改动比较大,基本上更新的频率在1天1次甚至1天2次,小程序的发布机制为:开发者向微信公众平台提交开发版、平台审核、审核通过后需要开发者确认发布、客户端更新为最新版本

但在此过程中,发现几个非常明显的问题,当我在微信公众平台点击发布最新版本以后,立即打开客户端进行查看,有时候客户端仍然为老版本,但小程序又不能像H5页面使用webpack打包,每次打包利用MD5生成唯一文件名,所以只能利用微信官方提供的API来进行强制更新。

首先讲一下微信小程序的运行机制

小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。 假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台态的小程序切换到前台,这个过程就是热启动;冷启动指的是用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动。

更新机制
小程序冷启动时如果发现有新版本,将会异步下载新版本的代码包,并同时用客户端本地的包进行启动,即新版本的小程序需要等下一次冷启动才会应用上。

运行机制官方说明

也就是说,只有当用户冷启动小程序时,才能检测到我们线上的最新版本,同时异步下载新版本代码包,但现在的问题是,如果用户使用完微信小程序,直接返回手机桌面或者关闭屏幕,此时小程序对于手机而言,状态为“后台运行”,所以必须在小程序中加入一套检测机制,使用户每次运行的都是最新版本的小程序。具体方法如下:

首先在app.js中写一个全局方法,我这里起的名字是updateCheck();

具体代码如下:

/**
   * 小程序更新机制,如果还保留在后台,页面在onShow过程中加载时,
   * 自动检测更新
   */
  updateCheck: function() {
    //console.log('执行新版本检测...');
    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() {
      // 新的版本下载失败
      wx.showToast({
        title: '新版本下载失败',
        icon: 'none',
      })

    });
  },

全局方法已经写好,那么在首页启动的时候,运行方法检测,这里选择在onShow这个生命周期中进行检测,原因为onLoad只运行一次,如果发生部分页面返回的情况,onShow依旧生效,代码如下:

在index.js的Page上方,引入APP全局变量

在其中的onShow方法中,调用全局方法即可:

  /**
   * onShow
   */
  onShow: function () {

    //运行检测更新
    APP.updateCheck();
  },

代码部分已经完成,现在不论客户端的启动方式是“热启动”“冷启动”,只要线上有新的版本,就会出现提示:

点击“知道了”,即可以冷启动的方式重启,立即更新至最新版本。