WebView 遇到的问题

WebView 遇到的问题

总结一些在开发中遇到的问题, 上一篇中也有部分描述:

WebView 的反思和记录 ---定制设置和常见问题

这篇文章主要记录一些WebView 出现的问题。

  1. onPageStarted() 被调用多次问题:

    因为网址的加载过程中存在重定向问题,所以会被调用多次。 这个是不可避免的,重定向后都是一个新的网址,肯定会重新再调用onPageStarted().

    如果在这个方法里面涉及到一些逻辑,尽可能在这个逻辑里面加入一些判断,保证想要执行的逻辑只执行一次,这也是有益于程序的。

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        progressBar.setVisibility(VISIBLE);
        progressBar.setProgress(0);
        
        if(!isLoading) {
            //isLoading 默认为false
            isLoading = true;
            ...
            ...
            //执行只需要执行一次的逻辑
        }
        
    }
    
    
    // 然后在`onPageFinished()` 里
    
    isLoading = false;
    
  1. 在onPageStarted() 调用webView.canGoBack() 返回 false 问题

    有时在加载网址的时候,需要对当前webview的状态进行判断,例如,自定义了一些前进、后退按钮,便需要实时的刷新按钮,需要在网址发生变化时监听webView;

    在onPageStarted()里设置监听,去获取webView 的状态,但是有时会出现上述问题,明明webview是可以返回的,在onPageStarted()里获取的值为false。

    解决方案: 经过测试onProgressChanged()方法的调用情况,发现,在网络的加载进度在30%左右以后,canGoBack() 才返回 true;所以可以在onProgressChanged() 里加入监听,或是在onPageFinished()里去监听 webView的状态。

  2. 在onPageFinished() 里去设置progressBar 不可见,仍然看到进度条显示出来:

    问题出现的原因,有些不清楚为什么,但是在设置的时候更改为以下便可以:

    progressBar.setVisibility(View.GONE);
    

    所以在自行设置的时候,可以设置progressBar 为GONE 而不是INVISIBLE;

  3. 在一些低版本上,会出现webview 销毁时 程序发生crash的情况:

    此类情况的出现,往往是webview销毁时出现了问题,可以仔细检查下自己代码的编写;

    webView销毁代码示例:

    if (webView != null) {
       // 要首先移除
       removeView(webView);
            
       // 清理缓存
       webView.stopLoading();
       webView.onPause();
       webView.clearHistory();
       webView.clearCache(true);
       webView.clearFormData();
       webView.clearSslPreferences();
       WebStorage.getInstance().deleteAllData();
       webView.destroyDrawingCache();
       webView.removeAllViews();
            
       // 最后再去webView.destroy();
       webView.destroy();
    }
    

    若是 webView.destroy() 放在了前面,则就会出现错误,需要把 webView.destroy()放在最后面。

  1. 上面的销毁 webview时,在低版本4.4以下,这样会出现错误,包 空指针,

    具体的原因还没有查明,有说是系统bug的,尚且原因不清楚,可做两种处理,第一种:

    if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
        //4.4 以下
        webView = null;
    } else {
        webView.destroy();
    }
    

    第二种:

    webView.destroy();
    webView = null;
    
    

    第二种这样不需要判断一些版本,是否效果会更好些?

  2. webview 快速销毁后, 可能会出现在onPageFinished() 等地方发生crash:

    出现的情况可能是加载了很多网页,然后快速点击back键, 退出程序,这时,有可能在部分地方webview 的回调仍在进行,但是webView 可能已经是空了的, 就是发生空指针的crash, 解决方法:在webView的回调函数中 如果要对webview进行操作,先进行一次判空处理:

    onPageFinished() {
        //
        ...
        if(webView != null) {
            ...
            //执行要做的有关webview操作的逻辑
            boolean canGoForward = webView.canGoForward();
        }
    }
    
  3. webView 加载视频时出现的问题: 全屏问题

    要想实现webview 全屏加载视频,需要在webView.setWebChromeClient()里重写onShowCustomView()onHideCustomView(),这两个方法。

    可能出现的问题:在切换过程中,背景有白色的底色或是黑色的其他背景闪动一下;

    原因: 可能是有根布局的背景色引起的,可自行检查。

  1. webView 加载视频时出现的问题: 按back键 视频仍在播放:

    应该是返回到:

    if(webView.canGoBack()) {
        webView.goBack();
    }  else {
        ...
    }
    
    

    webview可以canGoBack(), 成功goback()后 但是视频仍在播放

    webview不知道对视频的处理调用了那些接口,解决方法:

    在 webView.goBack() 前调用 webView.reload(); webView.stopLoading()

    webView.reload();
    webView.stopLoading();
    webView.goBack();
    

    这样可以让视频暂停。

    注:很多地方都说应该调用webView 的onPause()和onResume() 方法去暂停和控制播放视频,这种方式下面介绍。

  1. webView 加载视频时出现的问题: 按home键和多任务键 视频仍在播放:
此时根据用户习惯应该暂停视频,但是webview本身没有处理这些事件,需要咱们自己去处理。

首先去通过一个广播监听用户点击home键和多任务键, 在监听中,点击后调用webView.onPause();

在用户重新进入到程序中时,在onresume() 中调用webView.onResume();

**注:**有些地方是利用反射的机制实现的:

```
webView.getClass().getMethod("onPause").invoke(webView, (Object[]) null);
```

其实这是为了兼容低版本3.0以下,所以现在基本上不需要再去兼容3.0,不需要利用反射的模式去写。
  1. 在加载视频的过程中,点击某个视频,会出现webview不去触发onPageStarted()的情况:

    在某些视频网站,点击某个具体的视频,不会去调用webView 的onPageStarted(), onPageFinished();

    原因是因为 onPageStarted(), onPageFinished()都是 "main frame loading" 即 整页加载时才会回调,在某些视频网站上,点击某个视频可能不属于整页加载,故而不会去调用 onPageStarted(), onPageFinished()。

    这个问题可能会导致某些需求去刷新当前webview是否可前进和后退,可能导致后退的情况得不到及时的反馈(例如在onPageStarted()里去刷新状态,但是点击视频没有调用这个方法)。

    解决方法:一定会回调的方法是webView.setWebChromeClient() 中的 onProgressChanged(), 可以尝试在这里解决。

  2. 关于webview 图片加载的问题:

    在一般的设置里,都会设置图片的加载模式为:

    //webSetting设置
    if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        webSettings.setLoadsImagesAutomatically(false);
    } else {
        webSettings.setLoadsImagesAutomatically(true);
    }
    

    然后在onPageFinished()里设置:

    if(!webView.getSettings().getLoadsImagesAutomatically()) {
        webView.getSetting.setLoadsImagesAutomatically(true);
    }
    

    如果不设置的话,会出现在android 4.4以下 图片加载不出来的问题,因为手动设置为false了。

    上面的代码,其目的是对API 在19 以上的版本做了兼容,因为4.4以上系统在onPageFinished时再恢复图片加载时,如果存在多张图片引用的是相同的src时,会只有一个image标签得到加载,这样会造成界面不对的情况,所以4.4以上要在加载网页的时候就去主动加载图片,4.4以下可以等到onPageFinished()后再去加载图片(这样会首先去加载网页的界面,省去用户等待的时间)

  1. 关于 webView.clearCache(boolean includeDiskFiles) 清理的缓存问题:

    在源码里面可以看到关于这个方法的陈述:

    Clears the resource cache. Note that the cache is per-application, so
    this will clear the cache for all WebViews used.
    

    即整个app 的缓存是一份的,里面不光是webView 的缓存,还有其他的一些缓存,所以当去调用这个方法时,实际清理的缓存要多余webview 占用的内存。
    所以清理的时候要注意一下。

  2. 有关报错出现: 找不到 android.webkit.webViewClient 的错误
    记得之前看到了这个问题,当时一脸懵,啊?这怎么可能,肯定是用户手机哪里出错了,不用解这个 bug……?

    近期忽然看到这样一个说法, 有关混淆文件 proguard-rules.pro 的说法,当你使用到一些复杂的 webView 操作时,应该把下面部分的代码加入到 proguard-rules.pro 这个文件中:

    -keepclassmembers class * extends android.webkit.webViewClient {
        public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
        public boolean *(android.webkit.WebView, java.lang.String);
    }
    
    -keepclassmembers class * extends android.webkit.webViewClient {
          public void *(android.webkit.webView, java.lang.String);
    }
    

    这个部分确实没想到,但没找到具体的依据,不知道是不是这个原因造成的。

  1. To be continued

以上是我在项目开发中遇到的问题,可能不全面,有错误与有疑问的,请留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容