【cordova】cordova热更新插件的问题(cordova-hot-code-push)

来源:互联网 发布:linux shell脚本编程 编辑:程序博客网 时间:2024/05/20 22:03

现在估计没多少用cordova的公司了吧,然而迫于公司老总的要求,非要让用H5(明明不懂android,非要干涉技术,小领导们也是敢怒不敢言,唉,越说越气),在这儿随便记录一下吧,如果恰巧有谁也用这个,并且对你有所帮助,不胜荣幸。

cordova热更新用的是一个叫cordova-hot-code-push的插件(github地址: https://github.com/nordnet/cordova-hot-code-push ),具体使用步骤网上可以找到挺多,不再赘述(这里贴个地址http://www.zyyapp.com/post/116.html 网上好多教程写的不太好,我最终是按着这个的操作完成了的)。

今天主要说一下在使用这个插件时遇到的一个问题:进入app,并点了几个页面后,打算按设备返回键返回上一页,app却直接退出了;而且点击app左上角的返回图标,window.history.back()代码无效,没反应。

因为我们的项目中有很多自己写的插件,不是通过命令行安装的那种,所以必须采取手动添加插件的方式,一开始我还以为是我手动添加有地方搞错了的问题,就一点一点和正常命令行安装的demo项目比较。最后都一样之后还是有这个问题,不过我发现捕捉了返回事件的页面,会执行返回的逻辑,也就是说返回事件是没问题的,那么最大的嫌疑就是返回栈的问题了,在H5里面也就是history这个家伙了。

二话不说,打开chrome调试(如果不会使用chrome调试cordova app,可以参考我之前写过的一篇文章http://www.jianshu.com/p/1c5b307c315a ),在控制台看history,如下图,history的length是1,试了好几个页面都是这样。

Paste_Image.png

知道是history的原因了,但是还是不清楚是什么导致的history长度一直为1。

我学着广告中的人那样,抱着试试看的心态,打开了github的issues页面 = =”
惊喜的发现第一页就有一个标题为“After installed chcp , history.go(-1) become useless?” https://github.com/nordnet/cordova-hot-code-push/issues/262
这不就是我们遇到的同样的问题吗!点点点点进去!

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.

以上是作者对这个问题的答复,大体意思就是本来app的页面是加载assets目录下的文件,而这个插件是把assets目录的东西复制到外部存储中(用root浏览器确实可以在/data/user/0/包名/files/cordova-hot-code-push-plugin/目录下看到一些文件夹,里边就是我们的文件目录了,即www目录),然后重新指向到外部存储的页面,而这时候history里是有之前的assets目录下的历史记录的,如果不清除记录,即 webView.clearHistory() ,会导致用户有可能再通过返回栈(我就用android中的说法了)退回到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目录下的页面的,因为返回事件拦截掉了,然后我就试着把上边这几行代码注掉了,暂时没发现什么问题。

继续往下看代码,会发现几个重载的onEvent方法,显然是用到了eventbus,作者的命名和注释都很友好,很容易就可以看出是什么情况的回调。几个重载的参数分别是BeforeAssetsInstalledEvent、AssetsInstalledEvent、AssetsInstallationErrorEvent、UpdateIsReadyToInstallEvent、NothingToUpdateEvent、BeforeInstallEvent、UpdateDownloadErrorEvent、UpdateInstalledEvent、UpdateInstallationErrorEvent、NothingToInstallEvent,各个时候的回调一目了然,感兴趣的可以下载源码看一下。
看到这些方法我有一个想法,那就是为什么要在每一次页面初始化的时候都调用 webView.clearHistory(); 呢?我们是不是可以只在assets installed以及update installed的时候清除一下记录就好了呢?这样就不会每个页面都在初始化的时候就清除记录,只在需要的时候清除,也就不会有问题了。我在上边那条issue下向作者提出了这个想法,目前作者还没有回复我,也不知道我的考虑是否全面。

0 0
原创粉丝点击