ReactNative code-push更新后重新打开回退问题

问题:

使用code-push更新以后,关闭app重新打开会回滚到更新之前的版本,查看日志发现有这么一句话

Update did not finish loading the last time, rolling back to a previous version

更新判断代码如下

    CodePush.checkForUpdate().then((update) => {
      if (update) {
        CodePush.sync({
          updateDialog: {
            appendReleaseDescription: false,
            descriptionPrefix: '\n\n更新内容:\n',
            title: '发现新版本',
            mandatoryUpdateMessage: '更新内容:\n' + update.description,
            mandatoryContinueButtonLabel: '确定'
          }
        },
        this.codePushStatusDidChange.bind(this),
        this.codePushDownloadDidProgress.bind(this))
      }
    })

解决:

检查发现,是由于没有仔细阅读官方文档,文档中有这么一句话:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lkv9A73H-1587373233409)(/Users/hxl/Library/Application Support/typora-user-images/image-20200420162337555.png)]

翻译为:如果您没有在app启动时调用sync(例如在根组件的componentDidMount中),则需要在app启动时显式调用notifyApplicationReady,否则,插件将认为您的更新失败并回滚。

至于为什么要加,看下Android源码:

//CodePush.js 177行
void initializeUpdateAfterRestart() {
        ...
        JSONObject pendingUpdate = mSettingsManager.getPendingUpdate();
        if (pendingUpdate != null) {
            //有新的更新包可用
            JSONObject packageMetadata = this.mUpdateManager.getCurrentPackage();
            if (!isPackageBundleLatest(packageMetadata) && hasBinaryVersionChanged(packageMetadata)) {
                //版本不符
                CodePushUtils.log("Skipping initializeUpdateAfterRestart(), binary version is newer");
                return;
            }

            try {
                boolean updateIsLoading = pendingUpdate.getBoolean(CodePushConstants.PENDING_UPDATE_IS_LOADING_KEY);
                if (updateIsLoading) {
                    // Pending package已经被init过, 但是 notifyApplicationReady 没有被调用.因此认为这是个无效的更新并且rollback.
                    CodePushUtils.log("Update did not finish loading the last time, rolling back to a previous version.");
                    sNeedToReportRollback = true;
                    rollbackPackage();
                } else {
                    // 现在有个新的更新包可以运行,开始init这个更新包如果它崩溃了,需要在下一次启动时rollback
mSettingsManager.savePendingUpdate(pendingUpdate.getString(CodePushConstants.PENDING_UPDATE_HASH_KEY), /* isLoading */true);
                }
            } catch (JSONException e) {
                // Should not happen.
                throw new CodePushUnknownException("Unable to read pending update metadata stored in SharedPreferences", e);
            }
        }
    }

下载好更新包后,将这个更新包标志位pending package,并且isloading为false,将previousPacakge置为currentPackage,currentPackage置为下载的更新包。
在加载更新包时会判断这个更新包是否是pending package,如果是则判断isloading是否为false,如果为false则代表这个pending package是第一次加载,如果为true则代表这个pending被加载后调用notifyApplicationReady前发生崩溃,需要回滚。
如果发生回滚会将pending package置空,将previouPackage赋值给currentPackage。
在正确加载更新包后,应该手动触发notifyApplicationReady将pending package置空,代表这个更新包被正确installed。


1.解决办法一:

如果是入口处每次都调用了CodePush.sync则不会有问题,因为CodePush.sync函数中会调用notifyApplicationReady函数。

2.解决办法二:

根页面加载完成后调用CodePush.notifyAppReady函数,告知它已经加载成功了,可以清空记录了。

    CodePush.checkForUpdate().then((update) => {
      if (update) {
        CodePush.sync({
          updateDialog: {
            appendReleaseDescription: false,
            descriptionPrefix: '\n\n更新内容:\n',
            title: '发现新版本',
            mandatoryUpdateMessage: '更新内容:\n' + update.description,
            mandatoryContinueButtonLabel: '确定'
          }
        },
        this.codePushStatusDidChange.bind(this),
        this.codePushDownloadDidProgress.bind(this))
      } else {
        CodePush.notifyAppReady()
      }
    })
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值