RSS阅读器练习笔记————WebView中图片缓存
2013-03-11 21:46
309 查看
本文来自http://blog.csdn.net/chenshaoyang0011转载请申明出处!
在前面一篇笔记http://blog.csdn.net/chenshaoyang0011/article/details/8634235中,描述了解决XML中携带CDATA和HTML实体字符的解决办法,接下来要解决的问题就是缓存图片。
在这篇文章中主要记录了对以下问题的解决方法:
1、WebView中图片点击事件的响应
2、WebView图片缓存,并替换WebView默认图片(即图片未加载前显示的样式)
在新闻内容显示的时候,图片是必不可少的,在内容加载完毕之后,图片的缓存也是非常必要的,毕竟对于手机应用,流量是非常宝贵的资源。对于图片,WebView本身有一个缓存数据库进行缓存。但是我使用的是另外一个思路进行图片的缓存——阻止WebView加载图片而是在WebView将文本加载好了之后,通过本地方法下载图片保存到本地后再显示到WebView中。这样,在使用WebView进行显示的时候能够更加的灵活。
在实现上述提到的功能之前,需要了解Android的WebView如何实现Java代码与JavaScript代码的相互调用,推荐两篇博文http://blog.csdn.net/wangtingshuai/article/details/8631835 (实现简单调用)和http://blog.csdn.net/wangtingshuai/article/details/8635787 (实现图片点击)本文就不再赘述了。接下来就详细的探讨下上述功能的实现方法。
一、响应WebView中图片点击事件。
对于此功能的实现,可以参照http://blog.csdn.net/wangtingshuai/article/details/8635787 这篇文章。其中主要涉及到JS与JAVA代码的互调,这里我就不重新造轮子了。
二、缓存WebView中的图片,替换默认图片
WebView本身有自己的缓存机制,但是由于没有找到相关的文档,感觉不是很好用,所以我就想了另外一个方法。主要思路是这样的:1、使用jsoup来解析html;2、获取所有图片的URL(即img标签的url),替换为需要显示默认状态的图片的URI,最后在图片下载好后将这些URI按照某种映射规则替换为本地的URI(即相当于将这个img指向了本地的一张图片);3、关闭WebView加载图片,加载html;4、在文本加载完毕之后,开始依次下载所有的img到本地,每张图片下载好后,调用js代码刷新图片。
下面就一步一步的来实现。
1、使用jsoup解析html
这个我在http://blog.csdn.net/chenshaoyang0011/article/details/8640987 已经简单的介绍了,详细的使用还需参照http://jsoup.org/ (后文中代码使用了很多jsoup的api)。
2、获取所有图片的url,并替换为本地图片(需要用来替换WebView默认显示效果的图片)。
获取到的图片的url需要保存到一个属性List<String>中:
使用以下代码片段可以从html中获取所有img标签的url,并且按照如下映射规则替换为本地图片的URI(当然这个映射规则由自己定啦~~):"http://.../xx.xx"替换为"file://mnt/sdcard/test/xx.xx"其实就是将图片下载后保存的路径。
3、关闭WebView加载网络图片,加载html先显示文本内容
这样做主要是为了改善用户体验,阻止WebView自己加载图片是避免重复下载图片浪费流量。
首先关闭WebView加载网络图片,其实由于我们已经替换掉了img中url,可以忽略这一步。但是为了避免有漏网之鱼,还是加上好些:
webView.getSettings().setBlockNetworkImage(true);
接下来加载html:
4、在文本加载完毕之后,开始依次下载所有的img到本地,每张图片下载好后,调用js代码刷新图片。
文本内容加载完毕之后,就可以开始加载图片内容了,在html内容加载完之后,会调用WebViewClient.onPageFinished(WebView view, String url)这个方法。我们就可以在这个方法中执行图片的下载保存工作。
以下的代码片段就实现了开始下载的功能:
上面的代码中DownloadWebImgTask的实现如下,其功能就是批量的下载图片,并且在每张图片下载好后刷新WebView。由于WebView本身没有提供接口实现图片的单独刷新(至少我没有找到。。。),所以只能借助js来实现此功能。
这样图片就被正常的显示出来,并且在本地已经有缓存了。
最后照例给出一个简单的demo:http://download.csdn.net/detail/chenshaoyang0011/5130931
在前面一篇笔记http://blog.csdn.net/chenshaoyang0011/article/details/8634235中,描述了解决XML中携带CDATA和HTML实体字符的解决办法,接下来要解决的问题就是缓存图片。
在这篇文章中主要记录了对以下问题的解决方法:
1、WebView中图片点击事件的响应
2、WebView图片缓存,并替换WebView默认图片(即图片未加载前显示的样式)
在新闻内容显示的时候,图片是必不可少的,在内容加载完毕之后,图片的缓存也是非常必要的,毕竟对于手机应用,流量是非常宝贵的资源。对于图片,WebView本身有一个缓存数据库进行缓存。但是我使用的是另外一个思路进行图片的缓存——阻止WebView加载图片而是在WebView将文本加载好了之后,通过本地方法下载图片保存到本地后再显示到WebView中。这样,在使用WebView进行显示的时候能够更加的灵活。
在实现上述提到的功能之前,需要了解Android的WebView如何实现Java代码与JavaScript代码的相互调用,推荐两篇博文http://blog.csdn.net/wangtingshuai/article/details/8631835 (实现简单调用)和http://blog.csdn.net/wangtingshuai/article/details/8635787 (实现图片点击)本文就不再赘述了。接下来就详细的探讨下上述功能的实现方法。
一、响应WebView中图片点击事件。
对于此功能的实现,可以参照http://blog.csdn.net/wangtingshuai/article/details/8635787 这篇文章。其中主要涉及到JS与JAVA代码的互调,这里我就不重新造轮子了。
二、缓存WebView中的图片,替换默认图片
WebView本身有自己的缓存机制,但是由于没有找到相关的文档,感觉不是很好用,所以我就想了另外一个方法。主要思路是这样的:1、使用jsoup来解析html;2、获取所有图片的URL(即img标签的url),替换为需要显示默认状态的图片的URI,最后在图片下载好后将这些URI按照某种映射规则替换为本地的URI(即相当于将这个img指向了本地的一张图片);3、关闭WebView加载图片,加载html;4、在文本加载完毕之后,开始依次下载所有的img到本地,每张图片下载好后,调用js代码刷新图片。
下面就一步一步的来实现。
1、使用jsoup解析html
这个我在http://blog.csdn.net/chenshaoyang0011/article/details/8640987 已经简单的介绍了,详细的使用还需参照http://jsoup.org/ (后文中代码使用了很多jsoup的api)。
2、获取所有图片的url,并替换为本地图片(需要用来替换WebView默认显示效果的图片)。
获取到的图片的url需要保存到一个属性List<String>中:
public List<String> imgUrls = new ArrayList<String>();
使用以下代码片段可以从html中获取所有img标签的url,并且按照如下映射规则替换为本地图片的URI(当然这个映射规则由自己定啦~~):"http://.../xx.xx"替换为"file://mnt/sdcard/test/xx.xx"其实就是将图片下载后保存的路径。
Document doc = null; imgUrls.clear(); Elements es = doc.getElementsByTag("img"); for (Element e : es) { String imgUrl = e.attr("src"); imgUrls.add(imgUrl); String imgName; File file = new File(imgUrl); imgName = file.getName(); if(imgName.endsWith(".gif")){ e.remove(); }else{ String filePath = "file:///mnt/sdcard/test/" + imgName; e.attr("src","file:///android_asset/web_logo.png"); e.attr("src_link", filePath); e.attr("ori_link",imgUrl); String str = "window." + Js2JavaInterfaceName + ".setImgSrc('" + filePath + "')"; e.attr("onclick", str); } }
3、关闭WebView加载网络图片,加载html先显示文本内容
这样做主要是为了改善用户体验,阻止WebView自己加载图片是避免重复下载图片浪费流量。
首先关闭WebView加载网络图片,其实由于我们已经替换掉了img中url,可以忽略这一步。但是为了避免有漏网之鱼,还是加上好些:
webView.getSettings().setBlockNetworkImage(true);
接下来加载html:
//result为解析后获得的html文本 webView.loadDataWithBaseURL(null, result, "text/html", "utf-8", null);
4、在文本加载完毕之后,开始依次下载所有的img到本地,每张图片下载好后,调用js代码刷新图片。
文本内容加载完毕之后,就可以开始加载图片内容了,在html内容加载完之后,会调用WebViewClient.onPageFinished(WebView view, String url)这个方法。我们就可以在这个方法中执行图片的下载保存工作。
以下的代码片段就实现了开始下载的功能:
webView.setWebViewClient(new WebViewClient(){ public void onPageFinished(WebView view, String url){ //DownloadWebImgTask是用于下载图片的类 DownloadWebImgTask downloadTask = new DownloadWebImgTask(); //获取所有图片的url List<String> urlStrs = parser.getImgUrls(); String urlStrArray[] = new String[urlStrs.size() + 1]; urlStrs.toArray(urlStrArray); //开始下载 downloadTask.execute(urlStrArray); } });
上面的代码中DownloadWebImgTask的实现如下,其功能就是批量的下载图片,并且在每张图片下载好后刷新WebView。由于WebView本身没有提供接口实现图片的单独刷新(至少我没有找到。。。),所以只能借助js来实现此功能。
public class DownloadWebImgTask extends AsyncTask<String, String, Void>{ public static final String TAG = "DownloadWebImgTask"; @Override protected void onProgressUpdate(String... values) { super.onProgressUpdate(values); //加载下面的js代码实现单张图片的刷新 webView.loadUrl("javascript:(function(){" + "var objs = document.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);}" + "}" + "})()"); } @Override protected void onPostExecute(Void result) { //这段代码只是确保所有图片都顺利的显示出来 webView.loadUrl("javascript:(function(){" + "var objs = document.getElementsByTagName(\"img\"); " + "for(var i=0;i<objs.length;i++) " + "{" + " var imgSrc = objs[i].getAttribute(\"src_link\"); " + " objs[i].setAttribute(\"src\",imgSrc);" + "}" + "})()"); super.onPostExecute(result); } @Override protected Void doInBackground(String... params) { URL url = null; InputStream inputStream = null; OutputStream outputStream = null; HttpURLConnection urlCon = null; //若传入参数为空,则直接返回 if(params.length == 0) return null; File dir = new File(Environment.getExternalStorageDirectory() + "/test/"); if(!dir.exists()){ dir.mkdir(); } for(String urlStr : params){ try { if(urlStr == null){ break; } File tempFile = new File(urlStr); int index = urlStr.lastIndexOf("/"); String fileName = urlStr.substring(index + 1, urlStr.length()); File file = new File(Environment.getExternalStorageDirectory() + "/test/" + fileName); if(file.exists()){ continue; } try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } url = new URL(urlStr); urlCon = (HttpURLConnection)url.openConnection(); urlCon.setRequestMethod("GET"); urlCon.setDoInput(true); urlCon.connect(); inputStream = urlCon.getInputStream(); outputStream = new FileOutputStream(file); byte buffer[]=new byte[1024]; int bufferLength = 0; while((bufferLength = inputStream.read(buffer)) > 0){ outputStream.write(buffer, 0, bufferLength); } outputStream.flush(); publishProgress(urlStr); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { if(inputStream != null){ inputStream.close(); } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { if(outputStream != null){ outputStream.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return null; } }
这样图片就被正常的显示出来,并且在本地已经有缓存了。
最后照例给出一个简单的demo:http://download.csdn.net/detail/chenshaoyang0011/5130931
相关文章推荐
- RSS阅读器练习笔记————WebView中图片缓存
- webview中图片的获取、保存、展示、缓存处理
- Android/webview/图片硬缓存
- 基于SDWebImage 缓存图片 针对ImageView和Button
- 从WebView缓存中获取网页图片
- Android笔记:Webview 支持 input type=file选择上传图片
- WebView图片缓存
- android 从webview中读取缓存的图片
- webview点击事件,图片缓存
- iOS多线程-SDWebImage简单介绍 1 设置imageView的图片 (内存缓存&磁盘缓存) 1 [cell.imageView sd_setImageWithURL:[NSURL URL
- WebView缓存图片的获取
- Android开发笔记(一百五十二)H5通过WebView上传图片
- Android 从WebView缓存中获取网页图片
- tableView异步下载图片/SDWebImage图片缓存原理
- 《iOS开发笔记—SDWebImage图片缓存与清除》
- Android 从WebView缓存中获取网页图片
- webview 设定和使用缓存来获取网页中的js,css和图片资源
- Android 从WebView缓存中获取网页图片
- WebApp:如何让安卓的webview缓存webapp的html、js和图片等资源
- 几行代码实现WebView仅缓存图片