继续填坑 WebView

2,435 阅读3分钟

前言

这几天一直在和 WebView 打交道,根据踩到的一些坑在这里记录下来。

如何清除 WebView 的历史访问记录?

由于业务需要在订单支付成功后跳转 H5 的结果页面,但又不能让用户能够返回之前的流程,因此需要在用户成功跳转支付结果页面后将历史记录清除掉。在这之前我都是使用 WebView 的 clearHistory() 这个方法,其实这个方法就是清除历史记录,但在某些情况下可能出现异常情况,例如在成功跳转页面后再调用这个方法,试了很多次都无法将记录清除,后来发现了 WebView 的 doUpdateVisitedHistory(WebView view, String url, boolean isReload) 这个方法,在这个方法里调用 clearHistory() 基本每次都成功,至少我试了是这样,这个方法是 WebViewClient 的成员方法,需要重写使用。

再说说 doUpdateVisitedHistory(WebView view, String url, boolean isReload) 这个方法,我也遇到了一点问题,我一般是直接在里面调用 clearHistory() ,但某些特殊情况可能会出现页面无法跳转,针对这种情况我是在 doUpdateVisitedHistory(WebView view, String url, boolean isReload) 里面先进行页面跳转,然后再清除历史记录,这样就没问题了,至于为什么会出现跳转失败的原因,我还没弄明白,如果有人知道的话希望能告诉我。

关于 Cookie

关于 Cokkie 的这个问题困扰了我好几天,因为在目前开发的 app 上面,假设第一次安装完 app 然后登录,后续不管如何切换账号登录,跳转的 H5 页面都是第一个登录用户的数据,一开始以为是我代码里的一些问题,因为看到 ios 那边并没有出现这种情况。我把跳转的链接复制出来在浏览器打开,也会出现这种情况(我电脑手机的浏览器都是 Chrome),然后在昨天跟后台反馈后,把链接复制给他打开,嗯?!居然没出现这种数据异常的情况,瞄了一眼他用的浏览器,360浏览器。嗯......这时候我才大概猜测是浏览器的问题,试着把浏览器的缓存全部清了,再打开链接,已经不会出现那个问题了。到这里已经可以肯定是 Cookie 的锅了(开发经验不长,并没有想到 Cookie 导致的)。上网搜了一下 Android 如何清除 Cookie ,找到如下代码。

CookieManager.getInstance().removeCookie(ValueCallback callback);

如果需要兼容 5.0 以下版本的,这行代码是有问题的,需要改成下面这样

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    CookieManager.getInstance().removeAllCookies(null);
} else {
    CookieSyncManager.createInstance(this);
    CookieManager cookieManager = CookieManager.getInstance();
    if (cookieManager != null) cookieManager.removeAllCookie();
    CookieSyncManager.getInstance().sync();
}

如果不改的话,运行在 5.0 以下版本时就会报 NoSuchMethodError 的错误。

关于 HTML select 标签

如果 WebView 实例化所用的 Context 不是 Activity-Context ,那基本上 H5 页面想要展示的选择框是无法成功弹出的,原因是 select 标签要弹的选择框在 Android 平台是用 Dialog 来实现的,Dialog 必须使用 Activity-Context 来创建,而由于 WebView 实例化时没有传入 Activity-Context ,所以选择框无法弹出,甚至在 Android 低版本中 App 会出现 Crash 现象,因为在创建 WebView 的时候,应当使用 Activity-Context ,而不是 Application-Context(如果通过 findViewById 方法进行实例化则没有这个烦恼,主要是针对通过 new WebView() 来实例化的形式)。

Resources$NotFoundException

如果在 Lollipop(API 21~22) 上,这个异常很大几率会出现,原因是无法正常 intlate WebView ,但是在其他 OS 版本并不会出现这种问题,这时只要在 AndroidManifest 中,找到承载 WebView 的 Activity ,写上这么一段代码,就可以修复这个问题。

<activity android:name=".BrowserActivity"
    android:configChanges="uiMode"/>