Webview 图片异步加载及bug解决

原创 2013年12月02日 10:56:19

在项目中新闻显示需要使用图片的异步加载,并且在加载图片前和加载图片失败时显示默认图片。

关于webview中图片的异步加载的思路如下:

方案一:由前端同学全权负责(使用js实现异步加载)

方案二:android端进行处理

(1)  从相应请求获取到页面的数据,处理其中的img标签,将img标签中的src属性存储在img标签中的ori_link属性中,给img标签中的src属性赋值你默认图片所在路径,给img标签中的src_link属性赋值你的图片下载后保存的路径

 

 private voidhandleImageClickEvent(Document doc) {
     Elements container =doc.getElementsByTag("article");
     for (Element ce : container) {
        Elements es = ce.getElementsByTag("img");
        for (Element e : es) {
           String imgUrl = e.attr("src");
           if(!imgUrl.startsWith("http://")){
               imgUrl = Constants.PIC_URL+imgUrl;
           }
           imgUrls.add(imgUrl);
           String imgName;
           imgName = StrMD5.getStrMD5(imgUrl);;
           String filePath = "file:///mnt/sdcard/"
                  + Constants.WEB_IMAGE_CACHDIR + "/" +imgName;
           e.attr("src", "file:///android_asset/news_info_default_image.jpg");
           e.attr("src_link", filePath);
           e.attr("ori_link", imgUrl);
        }
    }

(2)  使用webview的loadDataWithBaseURL(Constants.BASE_URL, result,"text/html", "utf-8", null);

Constants.BASE_URL 是为了使在一些页面中使用js或其他方式访问自己工程相对路径资源的时候使用的。

(3)  重写webview的WebViewClient ,在onPageFinished方法中启动图片异步加载方法:

在task的doInBackground中下载图片并保存到sd卡指定位置,下载完一个就通知publishProgress(urlStr) urlStr是图片网址。

在task的onProgressUpdate方法中加载替换img属性的js:

@Override
  protected void onProgressUpdate(String...values) {
     super.onProgressUpdate(values);
 
     mNewsInfoWebview
           .loadUrl("javascript:(function(){"
                  +"var contener =document.getElementsByTagName(\"article\");"
                  +"var objs;"
                  +"for(var i=0;i<contener.length;i++){ varobjs=contener[i].getElementsByTagName(\"img\")}"
                  + "for(var i=0;i<objs.length;i++)  "
                  + "{"
                  + "    var imgSrc =objs[i].getAttribute(\"src_link\"); "
                  + "    var imgOriSrc =objs[i].getAttribute(\"ori_link\"); "
                  + " if(imgOriSrc == \"" + values[0] + "\"){"
                  + "   objs[i].setAttribute(\"src\",imgSrc);}"
                  + "}" + "})()");
}
 


 

Values是publishProgress传入的url

 

     但是这种方式有个问题:当用户sd卡不存在或者用户存储设备非标准时,图片无法显示。

为了解决这个问题,有一下两个方案:

(一)  使用多级缓存:mem+?+sd ?可以使数据库,可以使非sd卡之外存储位置(暂时未进行了解)

(二)  直接使用webview自带缓存:

(1)  修改webview缓存模式:webview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

(2)  在获取服务器端html时对img进行以下处理:

e.attr("src", "file:///android_asset/news_info_default_image.png");
e.attr("onerror","this.src='file:///android_asset/news_info_default_image.png'");
        e.attr("ori_link", imgUrl);


onerror方法是当图片加载不出来时,浏览器默认显示图片

启动后台异步加载图片方法不再写文件,而是直接调用js方法进行url替换:

  

@Override
  protected voidonProgressUpdate(String... values) {
     super.onProgressUpdate(values);
     mNewsInfoWebview
     .loadUrl("javascript:(function(){"
           + "var objs = document.getElementsByTagName(\"img\");"
           + "for(var i=0;i<objs.length;i++)  "
           + "{"
           + "    var imgOriSrc =objs[i].getAttribute(\"ori_link\"); "
           + " if(imgOriSrc == \"" + values[0] + "\"){"
           + "    objs[i].setAttribute(\"src\",imgOriSrc);}"
           + "}" + "})()");
  }

 

 

总结:由于每次加载页面都是通过loadDataWithBaseURL方法,所以即使服务器端页面有进行修改,也不会由于浏览器缓存造成不能更新的问题。但是更新频繁就会造成缓存文件过多,因此需要增加机制清理缓存。

Android与WebView的同步和异步访问机制

WebChromeClient和WebViewClient是WebView应用中的两个最重要的类。 通过这两个类,WebView能够捕获到Html页面中url的加载,javascript的执行等的所有...
  • foolsheep
  • foolsheep
  • 2014年08月04日 13:25
  • 6677

Android WebView shouldInterceptRequest 异步加载

WebView 的 shouldInterceptRequest 可以让我们监听WebView发出的请求并做相应的处理,但有个严重的问题:浏览器的渲染以及资源加载都是在一个线程中,如果在shouldI...
  • u013414710
  • u013414710
  • 2016年11月03日 15:57
  • 2803

WebView和ListView的交互使用,异步加载的问题

我用了一个listView来装载多个WebView。每个WebView的数据都是在后台进行加载的。现在有个问题就是,在所有View全部创建完毕后,listView中不可见的WebView,即使已经把数...
  • wangsuo5764
  • wangsuo5764
  • 2017年01月02日 12:15
  • 66

【Android】异步加载解决方案

Android的Lazy Load主要体现在网络数据(图片)异步加载、数据库查询、复杂业务逻辑处理以及费时任务操作导致的异步处理等方面。在介绍Android开发过程中,异步处理这个常见的技术问题之前,...
  • Etzmico
  • Etzmico
  • 2013年11月08日 18:17
  • 6850

Android WebView页面加载优化

目前webapp越来越多,体验也越来越好,为了能够更好的使用WebView展示出流畅的的页面,可以从以下几点做优化: WebView缓存资源文件本地存储减少耗时操作客户端UI优化 可能有人...
  • dliyuedong
  • dliyuedong
  • 2015年07月18日 22:46
  • 40810

UIWebView发送异步(同步)请求加载网页

一,从网络加载数据显示在webView的过程      1,首先得知要访问的资源路径URL,           2,根据URL 向服务器发送请求,请求得到这个路径上的资源           3...
  • theroadofprogrammers
  • theroadofprogrammers
  • 2014年09月26日 09:31
  • 1518

Android WebView shouldInterceptRequest 异步加载 - 屠龙宝刀,点击就送,极品装备,一秒刷爆

WebView 的 shouldInterceptRequest 可以让我们监听WebView发出的请求并做相应的处理,但有个严重的问题:浏览器的渲染以及资源加载都是在一个线程中,如果在shouldI...
  • mocanjun0912
  • mocanjun0912
  • 2015年05月19日 16:13
  • 1014

Android WebView实现离线加载功能

android开发中难免会使用一些网页来展示某些数据,然而有的网页内容可能是基本上不会变的,每次加载既耗资源又耗流量,假如网络不好用户体验还会很差,这个时候适当的用一些缓存就很有必要了,无论是andr...
  • shaohongxuan
  • shaohongxuan
  • 2015年08月27日 18:20
  • 2227

Android WebView先加载网页文字,后加载图片

代码如下: public class MainActivity extends Activity {WebView webView; String url="http://222.180.239.9...
  • JimTrency
  • JimTrency
  • 2016年08月04日 13:01
  • 3026

android:webview加载网页速度很慢的的究极解决方案

Android客户端中混搭HTML页面,会出现虽然HTML内容载入完成,标题也正常显示,但是整个网页需要等到近5秒(甚至更多)时间才会显示出来。研究了很久,搜遍了国外很多网站,也看过PhoneGap的...
  • mygrilzhuyulin
  • mygrilzhuyulin
  • 2016年12月07日 09:21
  • 1525
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Webview 图片异步加载及bug解决
举报原因:
原因补充:

(最多只允许输入30个字)