RSS reader practice notes — WebView picture cache

This article is fromhttp://blog.csdn.net/chenshaoyang0011

In the previous note http://www.voidcn.com/article/p-tghalzgl-em.html, the solution is describedXMLXML span>Carry inCDATAandHTMLThe solution to physical characters, the next problem to be solved is to cache pictures.

This article mainly records the solutions to the following problems :

1,< /span>Response to the picture click event in WebView

2,WebView Picture cache, andReplace the default WebView picture (that is, the style displayed before the picture is loaded)

In the news content When displaying, pictures are indispensable. After the content is loaded, the caching of pictures is also very necessary. After all, for mobile applications, traffic is a very precious resource. For pictures, WebView itself has a cache database for caching. But what I use is another idea for image caching-to prevent WebView from loading the image, but after the WebView loads the text, download the image through the local method and save it locally before displaying it in the WebView. In this way, it can be more flexible when using WebView for display.

Before implementing the functions mentioned above, you need to understand How does Android’s WebView implement mutual calls between Java code and JavaScript code? Two blog posts are recommended http://blog.csdn.net/wangtingshuai/article/details/8631835 (implementation of simple calls) and http://www.voidcn.com /article/p-tvdfmyhz-nm.html (Implement image click) This article will not repeat it. Next, we will discuss the implementation methods of the above functions in detail.

一, Respond to the picture click event in WebView.

For the realization of this function, please refer to http ://www.voidcn.com/article/p-tvdfmyhz-nm.html This article. Which mainly involves the intermodulation of JS and JAVA code, here I will not reinvent the wheel.

Two , Cache the picture in the WebView, replace the default picture

WebView itself has its own caching mechanism, but because I didn’t find the relevant documents, it didn’t feel very useful, so I thought of another method. The main idea is as follows: 1. Use jsoup to parse html; 2. Get the URLs of all pictures (that is, the url of the img tag), replace them with the URIs of the pictures that need to display the default state, and finally follow these URIs after the pictures are downloaded Replace a certain mapping rule with a local URI (that is, point the img to a local picture); 3. Close the WebView to load the picture and load the html; 4. After the text is loaded, start to download all the imgs to Locally, after each picture is downloaded, call the js code to refresh the picture.

The following is a step by step implementation.

1 Use jsoup to parse html

This I am at http: //www.voidcn.com/article/p-uzbecwwk-em.html has been briefly introduced, and for detailed usage, please refer to http://jsoup.org/ (the code in the following uses many jsoup apis).

2 Get the urls of all pictures and replace them with local pictures (need to replace the pictures with the default display effect of WebView).

The url of the obtained picture needs to be saved in an attribute List:

[java] view plain copy

  1. public List imgUrls = new ArrayList();


Use the following code snippets to get the URLs of all img tags from html, and follow the mapping rules below Replace with the URI of the local picture (Of course, this mapping rule is up to you~~): “http://…/xx.xx” is replaced with “file://mnt/sdcard/test/xx.xx” is actually the path where the image is saved after downloading.

[java] view plain copy

  1. Document doc = null; ​/span>

  2. ImgUrls.clear();

  3. Elements es = doc.getElementsByTag(“img”);

  4. for (Element e: es) {< /span>

  5. String imgUrl = e.attr(“src”);

  6. imgUrls.add(imgUrl);

  7. < li>

    String imgName;

  8. File file = new File(imgUrl );

  9. imgName = file.getName();

  10. if(imgName.endsWith(“.gif”)){

  11. e.remove();

  12. }else{ < /span>

  13. String filePath = “file:///mnt/sdcard/test/ “ + imgName;

  14. e.attr(“src”,“file:///android_asset/web_logo.png”);

  15. e.attr(“src_link”, filePath);

  16. e.attr(“ori_link”,imgUrl);

  17. String str = “window.” + Js2JavaInterfaceName + “.setImgSrc(‘”

  18. + filePath + “‘)”;

    < /li>

  19. e.attr(“onclick”, str);

< br style="font-family:arial;font-size:14px;line-height:2 6px;background-color:#ffffff;">

3, close WebView to load network pictures, load html and display first Text content

This is mainly to improve the user experience. Preventing WebView from loading images by itself is to avoid repetitive downloading of images to avoid wasting traffic.

First, close the WebView to load the network image. In fact, since we have replaced the url in the img, this step can be ignored. But in order to avoid fish that slip through the net, it is better to add:

webView.getSettings().setBlockNetworkImage(true);

Next load html:
< /p>

[java] view plain copy

  1. //result is the html text obtained after parsing span>

  2. webView.loadDataWithBaseURL(null , result, “text/html”, “utf-8”, null); span>


4. After the text is loaded After that, start to download all imgs to the local in turn. After each picture is downloaded, call the js code to refresh the picture.

After the text content is loaded, you can start to load the image content. After the html content is loaded After that, the method WebViewClient.onPageFinished(WebView view, String url) will be called. We can download and save the image in this method.

The following code snippet realizes the function of downloading:

[java] view plain copy

  1. webView.setWebViewClient(new WebViewClient(){

  2. publicvoid onPageFinished(WebView view, String url){

  3. //DownloadWebImgTask is a class for downloading pictures

  4. DownloadWebImgTask downloadTask = new DownloadWebImgTask();

  5. //Get the url of all pictures

  6. List urlStrs = parser.getImgUrls ();

  7. String urlStrArray[] = new String[urlStrs.size() + 1];

  8. urlStrs.toArray(urlStrArray);

  9. //Start downloading

  10. downloadTask.execute(urlStrArray);

  11. });


The implementation of DownloadWebImgTask in the above code is as follows, its function is to download pictures in batches, and refresh the WebView after each picture is downloaded. Since WebView itself does not provide an interface to realize the separate refresh of the picture (at least I did not find it…), this function can only be realized with the help of js.

[java] view plain copy

  1. publicclass DownloadWebImgTask < span class="keyword" style="margin:0px;padding:0px;border:none;color:#006699;background-color:inherit;font-weight:bold;">extends AsyncTask{

  2. publicstaticfinal String TAG = “DownloadWebImgTask” ;  

  3. @Override

  4. protectedvoid onProgressUpdate(String… values) {  

  5. super.onProgressUpdate(values);  

  6. //加载下面的js代码实现单张图片的刷新

  7.                webView.loadUrl(“javascript:(function(){“ +    

  8. “var objs = document.getElementsByTagName(\”img\”); “ +    

  9. “for(var i=0;i +    

  10. “{“

  11.                        + ”    var imgSrc = objs[i].getAttribute(\”src_link\”); “

  12.                        + ”    var imgOriSrc = objs[i].getAttribute(\”ori_link\”); “

  13.                        + ” if(imgOriSrc == \”” + values[0] + “\”){ “

  14.                        + ”    objs[i].setAttribute(\”src\”,imgSrc);}” +  

  15. “}” +    

  16. “})()”);  

  17.            }  

  18. @Override

  19. protectedvoid onPostExecute(Void result) {  

  20. //这段代码只是确保所有图片都顺利的显示出来

  21.                webView.loadUrl(“javascript:(function(){“ +    

  22. “var objs = document.getElementsByTagName(\”img\”); “ +    

  23. “for(var i=0;i +    

  24. “{“

  25.                                + ”    var imgSrc = objs[i].getAttribute(\”src_link\”); “ +  

  26. ”    objs[i].setAttribute(\”src\”,imgSrc);” +  

  27. “}” +    

  28. “})()”);  

  29. super.onPostExecute(result);  

  30.            }  

  31. @Override< /p>

  32. protected Void doInBackground(String… params) {  

  33.                URL url = null;  

  34.                InputStream inputStream = null;  

  35.                OutputStream outputStream = null;  

  36.                HttpURLConnection urlCon =  null;  

  37. //若传入参数为空,则直接返回

  38. if(params.length == 0)  

  39. returnnull;  

  40.                File dir = new File(Environment.getExternalStorageDirectory() + “/test/”);  

  41. if(!dir.exists()){  

  42.                    dir.mkdir();  

  43.                }  

  44. for(String urlStr : params){  

  45. try {  

  46. if(urlStr == null){  

  47. break;  

  48.                        }  

  49.                        File tempFile = new File(urlStr);  

  50. int index = urlStr.lastIndexOf(“/”);  

  51.                        String fileName = urlStr.substring(index + 1, urlStr.length());  

  52.                        File file = new File(Environment.getExternalStorageDirectory() + “/test/” + fileName);  

  53. if(file.exists()){  

  54. continue;  

  55.                        }  

  56. try {  

  57.                            file.createNewFile();  

  58.                        } catch (IOException e) {  

  59.                            e.printStackTrace();  

  60.                        }  

  61.                        url = new URL(urlStr);  

  62.                        urlCon = (HttpURLConnection)url.openConnection();  

  63.                        urlCon.setRequestMethod(“GET”);  

  64.                        urlCon.setDoInput(true);  

  65.                        urlCon.connect();  

  66.                        inputStream = urlCon.getInputStream();  

  67.                        outputStream = new FileOutputStream(file);  

  68. byte buffer[]=newbyte[1024];  

  69. int bufferLength = 0;  

  70. while((bufferLength = inputStream.read(buffer)) > 0){  

  71.                            outputStream.write(buffer, 0, bufferLength);  

  72.                        }  

  73.                        outputStream.flush();  

  74.                        publishProgress(urlStr);  

  75.                    } catch (MalformedURLException e) {  

  76. // TODO Auto-generated catch block

  77.                        e.printStackTrace();  

  78.                    } catch (IOException e) {  

  79. // TODO Auto-generated catch block

  80.                        e.printStackTrace();  

  81.                    }finally{  

  82. try {  

  83. if(inputStream != null){  

  84.                                inputStream.close();  

  85.                            }  

  86.                        } catch (IOException e1) {  

  87. // TODO Auto-generated catch block

  88.                            e1.printStackTrace();  

  89.                        }  

  90. try {  

  91. if(outputStream != null){  

  92.                                outputStream.close();  

  93.                            }  

  94.                        } catch (IOException e) {  

  95. < p>// TODO Auto-generated catch block

  96.                            e.printStackTrace();  

  97.                        }  

  98.                    }  

  99.                }  

  100. returnnull;  

  101.            }  

  102.        }  

   这样图片就被正常的显示出来,并且在本地已经有缓存了。

   最后照例给出一个简单的demo:http://download.csdn.net/detail/chenshaoyang0011/5130931

[java] view plain copy

  1. public List imgUrls = new ArrayList();  

[java] view plain copy

[java] view plain copy

[java] view plain copy

  1. Document doc = null;  

  2.        imgUrls.clear();  

  3. Elements es = doc.getElementsByTag(“img”);  

  4. for (Element e : es) {  

  5.            String imgUrl = e.attr(“src”);  

  6.            imgUrls.add(imgUrl);  

  7.            String imgName;  

  8.            File file = new File(imgUrl);  

  9.            imgName = file.getName();  

  10. if(imgName.endsWith(“.gif”)){  

  11.                e.remove();  

  12.            }else{  

  13.                String filePath = “file:///mnt/sdcard/test/” + imgName;  

  14.                e.attr(“src”,“file:///android_asset/web_logo.png”);  

  15.                e.attr(“src_link”, filePath);  

  16.                e.attr(“ori_link”,imgUrl);  

  17.                String str = “window.” + Js2JavaInterfaceName + “.setImgSrc(‘”

  18.                        + filePath + “‘)”;  

  19.                e.attr(“onclick”, str);  

  20.            }  

  21.        }  

[java] view plain copy

[java] view plain copy

[java] view plain copy

  1. //result为解析后获得的html文本

  2. webView.loadDataWithBaseURL(null, result, “text/html”, “utf-8”, null);  

[java] view plain copy

[java] view plain copy

[java] view plain copy

  1. webView.setWebViewClient(new WebViewClient(){  

  2. publicvoid onPageFinished(WebView view, String url){  

  3. //DownloadWebImgTask是用于下载图片的类

  4.                DownloadWebImgTask downloadTask = new DownloadWebImgTask();  

  5. //获取所有图片的url

  6.                List urlStrs = parse r.getImgUrls();  

  7.                String urlStrArray[] = new String[urlStrs.size() + 1];  

  8.                urlStrs.toArray(urlStrArray);  

  9. //开始下载

  10.                downloadTask.execute(urlStrArray);  

  11.            }  

  12.        });  

[java] view plain copy

[java] view plain copy

[java] view plain copy

  1. publicclass DownloadWebImgTask extends AsyncTask{  

  2. publicstaticfinal String TAG = “DownloadWebImgTask”;  

  3. @Override

  4. protectedvoid onProgressUpdate(String… values) {  

  5. super.onProgressUpdate(values);  

  6. //加载下面的js代码实现单张图片的刷新

  7.                webView.loadUrl(“javascript:(function(){“ +    

  8. “var objs = document.getElementsByTagName(\”img\”); “ +    

  9. “for(var i=0;i +    

  10. “{“

  11.                        + ”    var imgSrc = objs[i].getAttribute(\”src_link\”); “

  12.                        + ”    var imgOriSrc = objs[i].getAttribute(\”ori_link\”); “

  13.                        + ” if(imgOriSrc == \”” + values[0] + “\”){ “

  14.                        + ”    objs[i].setAt tribute(\”src\”,imgSrc);}” +  

  15. “}” +    

  16. “})()”);  

  17.            }  

  18. @Override

  19. protectedvoid onPostExecute(Void result) {  

  20. //这段代码只是确保所有图片都顺利的显示出来

  21.                webView.loadUrl(“javascript:(function(){“ +    

  22. “var objs = document.getElementsByTagName(\”img\”); “ +    

  23. “for(var i=0;i +    

  24. “{“

  25.                                + ”    var imgSrc = objs[i].getAttribute(\”src_link\”); “ +  

  26. ”    objs[i].setAttribute(\”src\”,imgSrc);” +  

  27. “}” +    

  28. “})() “);  

  29. super.onPostExecute(result);  

  30.            }  

  31. @Override

  32. protected Void doInBackground(String… params) {  

  33.                URL url = null;  

  34.                InputStream inputStream = null;  

  35.                OutputStream outputStream = null;  

  36.                HttpURLConnection urlCon =  null;  

  37. //若传入参数为空,则直接返回

  38. if(params.length == 0)  

  39. returnnull;  

  40.                File dir = new File(Environment.getExternalStorageDirec tory() + “/test/”);  

  41. if(!dir.exists()){  

  42.                    dir.mkdir();  

  43.                }  

  44. for(String urlStr : params){  

  45. try {  

  46. if(urlStr == null){  

  47. break;  

  48.                        }  

  49.                        File tempFile = new File(urlStr);  

  50. int index = urlStr.lastIndexOf(“/”);  

  51.                        String fileName = urlStr.substring(index + 1, urlStr.length());  

  52.                        File file = new File(Environment.getExternalStorageDirectory() + “/test/” + fileName);  

  53. if(file.exists()){  

  54. continue;  

  55.                        }  

  56. try {  

  57.                            file.createNewFile();  

  58.                        } catch (IOException e) {  

  59.                            e.printStackTrace();  

  60.                        }  

  61.                        url = new URL(urlStr);  

  62.                        urlCon = (HttpURLConnection)url.openConnection();  

  63.                        urlCon.setRequestMethod(“GET”);  

  64.                        urlCon.setDoInput(true);  

  65.                        urlCon.connect();  

  66.                        inputStream = urlCon.getInputStream();  

  67.                        outputStream = new FileOutputStream(file);  

  68. byte buffer[]=newbyte[1024];  

  69. int bufferLength = 0;  

  70. while((bufferLength = inputStream.read(buffer)) > 0){  

  71.                            outputStream.write(buffer, 0, bufferLength);  

  72.                        }  

  73.                        outputStream.flush();  

  74.                        publishProgress(urlStr);  

  75.                    } catch (MalformedURLException e) {  

  76. // TODO Auto-generated catch block

  77.                        e.printStackTrace();  

  78.                    } catch (IOException e) {  

  79. // TODO Auto-generated catch block

  80.                        e.printStackTrace();  

  81.                    }finally{  

  82. try {  

  83. if(inputStream != null){  

  84.                                inputStream.close();  

  85.                            }  

  86.                        } catch (IOException e1) {  

  87. // TODO Auto-generated catch block

  88.                            e1.printStackTrace();  

  89.                        }  

  90. try {  

  91. if(outputStre am != null){  

  92.                                outputStream.close();  

  93.                            }  

  94.                        } catch (IOException e) {  

  95. // TODO Auto-generated catch block

  96.                            e.printStackTrace();  

  97.                        }  

  98.                    }  

  99.                }  

  100. returnnull;  

  101.            }  

  102.        }  

[java] view plain copy

[java] view plain copy

Leave a Comment

Your email address will not be published.