Cordova 热更新无历史记录解决方案

这篇记录一次cordova 热更新插件导致的历史记录不存在的问题。

一 情况说明

热更新插件:

使用后发现,手机的回退按钮无法实现页面回退而是项目推出。
在控制台测试发现历史记录为空。
网上查阅了一下资料发现cordova 的热更新插件会导致历史记录不可用

You probably already saw a description in the comments, why this is done. But anyways:

When we launch the app - it points to the index.html in the assets folder. But we want it to work with the content from the external storage (where our updated code is placed). So we redirect user to that “external” index.html. But browser (WebView) tracks that in it’s history. Without webView.clearHistory() when user clicks back button on the device - he will return to the index page from the assets, and we don’t want that.

Same thing will happen if we downloaded new content from the server, installed it and reloaded the page. Again, we are changing the directory and the page. And if user clicks on back button - he will return to the old page.

That’s why we clear history when page is initialised. But this might be an issue if you’r app is multy-page application: if for each navigation you load new page in the WebView - then plugin is re-initialised and history get cleaned.

来自于:asAnotherJack
其中这位博主提供了一种解决方案:
链接:https://www.jianshu.com/p/3d869a6a8398

如果对热更新有一定了解就会明白,我们初始会有一个原版的文件夹(位于assets目录下的文件),当对比更新数据发现需要热更新的时候,会额外创建一个新的文件夹,然后将相关的新文件复制进去,然后将系统的引用指向该文件夹,实现了热更新的伪操作。所以热更新不是覆盖,而是新增,这就会出现一些问题。

当我们热更新后没有清楚记录的时候,此时history里是有之前的assets目录下的历史记录的,返回会导致用户可能再通过返回栈退回到assets目录下的页面。

二 解决方案

第一种修改源码

来自于上面的博主,

打开位于src目录下的com\nordnetab\chcp\main\HotCodePushPlugin.java,熟悉cordova的都了解,这个继承自CordovaPlugin的家伙就是原生和h5交互的桥梁,在这个里边发现了一个jsInit(CallbackContext callback)方法,看名字也差不多知道是初始化的时候调用的,里边果然发现了这么一段代码:
// Clear web history.
// In some cases this is necessary, because on the launch we redirect user to the
// external storage. And if he presses back button - browser will lead him back to
// assets folder, which we don’t want.
handler.post(new Runnable() {
@Override
public void run() {
webView.clearHistory();
}
});
注释也写的很清楚了。
然后因为我们目前的app,在首页是有返回事件的拦截的(弹了一个对话框询问是否确认退出),那也就是说,我们的app是无论如何都没办法退回到旧的assets目录下的页面的,因为返回事件拦截掉了,然后我就试着把上边这几行代码注掉了,暂时没发现什么问题。

第二种 纯前端

处于项目的可维护性,插件是git下来的,不想通过频繁修改源码,后期非开发人员维护会非常麻烦,所以考虑用纯前端的方式解决这种问题。

解决思路很简单,因为cordova更新后,都会返回首页,所以我们在非首页的页面手动生成历史记录存放在storage缓存中,然后通过相关的事件监听实现一种回退功能。

下面是详细的代码:

function transitionLocation(pagecode, backpage, tourl) {
     window.localStorage.setItem("historyurl", pagecode + "," + backpage);
    if (isnotnull(tourl)) {
        window.location.href =tourl;
    }

}

function locationold(type, url, message) {
    var old = window.localStorage.getItem("historyurl");
    var thisurl = window.location.pathname;
    var endurl = "../index";
    if (isnotnull(old) && old.length > 10) {
        var arrays = old.split(",");
        if (thisurl.indexOf(arrays[0]) > 0 && isnotnull(arrays[1])) {
             window.localStorage.setItem("historyurl", "");
            endurl = arrays[1];
        } else if (isnotnull(url)) {
            endurl = url;
        } else {
            app.alert("页面跳转出现异常", endurl);
        }
    } else if (isnotnull(url)) {
        endurl = url;
    } else {
        app.confirm(function () {
            window.location.href = endurl;
        }, "跳转出现异常,是否返回首页?");
    }
    if (isnotnull(message) && message.length > 5) {
          alert(message, endurl);
    } else {
        window.location.href = endurl;
    }
}

逻辑很简单:
transitionLocation(“filter”, “thisurl”, "tourl ");

  • thisurl:在跳后页面回跳到之前页面运行的地址
  • tourl :当前页面要跳转到跳转页面说走的地址
  • filter : 判断historyurl 对当前页面有用

在这里插入图片描述

当返回的时候,

  locationold("type", "default");

type:扩展属性,用于灵活扩展,这里没有用处
default:用于不存在history时的默认跳转

这种方法的缺点在于需要在跳转前进行封装.

扩展

这种方法是可以扩展,通过扩展解决上述问题

我们可以通过监听popstatus 来判断是否按的返回键

第一步、将 myApp 目录下 config.xml <chcp> <auto-download enabled="true" /> <auto-install enabled="true" /> <config-file url="http://192.168.1.34:8080/myApp/www/chcp.json" /> <local-development enabled="true" /> </chcp> 地址改为自己的地址。 第二步、将myApp\platforms\android\app\src\main\res\xml目录下 config.xml <chcp> <auto-download enabled="true" /> <auto-install enabled="true" /> <config-file url="http://192.168.1.34:8080/myApp/www/chcp.json" /> <local-development enabled="true" /> </chcp> 第三步、myApp\platforms\android\app\src\main\assets 目录下 .chcpenv { "content_url": "http://192.168.1.34:8080/myApp/www/", "config_url": "http://192.168.1.34:8080/myApp/www/chcp.json" } cordova-hcp.json { "autogenerated": true, "update": "start", "content_url": "http://192.168.1.34:8080/myApp/www/" } 的 地址改为自己的 地址 第四步、将android项目导入Android Studio 第五步、 myApp\platforms\android\app\src\main\assets 目录下 执行 cordova-hcp build 命令后将www 目录下的所有文件拷贝到你自己的 文件服务器上。 第六步、启动服务器 第七步、发布安装app程序。 第八步、修改www目录下的文件信息,重新执行第五步。 第七步、再次打开app程序("update": "start",需两次)。 cordova-hcp.json { "autogenerated": true, "update": "start", "content_url": "http://192.168.1.34:8080/myApp/www/" } start - app启动时安装更新. 默认值. resume - app从后台切换过来的时候安装更新. now - web内容下载完毕即安装更新. 注意:网站的路径
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值