This article is from http://blog.csdn.net/chenshaoyang0011!
In the previous note.
This article mainly records the solutions to the following problems:
1,Response to image click events in webview
2,Cache the webview image and replace the default webview image (that is, the style displayed before the image is loaded)
When the news content is displayed, images are indispensable. After the content is loaded, the image cache is also necessary. After all, for mobile apps, traffic is a very valuable resource. For images, webview itself has a cache database for caching. However, I used another method to cache images-to prevent webview from loading images, but after webview loads the text, download the image locally and save it to the local directory before it is displayed in webview. In this way, you can use webview for more flexible display.
Before implementing the functions mentioned above, we need to know how Android webview achieves mutual calls between Java code and JavaScript code. We recommend two blog http://blog.csdn.net/wangtingshuai/article/details/8631835 (simple call) and http://blog.csdn.net/wangtingshuai/article/details/8635787 (achieve image click) This article will not go into detail. Next, we will discuss in detail the implementation methods of the above functions.
1. Respond to the image Click Event in webview.
For the implementation of this feature, refer to the http://blog.csdn.net/wangtingshuai/article/details/8635787 article. This mainly involves the interaction between JS and Java code. Here I will not recreate the wheel.
2. cache images in webview and replace default Images
Webview itself has its own caching mechanism, but it does not feel very useful because it does not find relevant documents, so I thought of another method. The main idea is as follows: 1. Use jsoup to parse HTML; 2. Obtain the URLs of all images (that is, the URLs of the IMG tags) and replace them with the Uris of images whose default status is to be displayed, finally, after the image is downloaded, replace these URIs with the local Uris according to some ing rules (that is, point the IMG to a local image). 3. Disable webview to load the image, 4. After the text is loaded, download all IMG files to the local device sequentially. After each image is downloaded, call the JS Code to refresh the image.
The following is a step-by-step implementation.
1. parse HTML using jsoup
This I have briefly introduced in the http://blog.csdn.net/chenshaoyang0011/article/details/8640987, detailed use also need to refer to the http://jsoup.org/(the code below uses a lot of jsoup APIs ).
2. Obtain the URLs of all images and replace them with local images (the default display effect of webview images must be replaced ).
The URL of the obtained image needs to be saved to the attribute list <string>:
public List<String> imgUrls = new ArrayList<String>();
You can use the following code snippet to obtain the URLs of all IMG tags from HTML, and replace them with the URI of the local image according to the following ing rules (of course, this ing rule is set by yourself ~~) : "Http ://... /xx. xx "is replaced with" file: // MNT/sdcard/test/xx. xx "is actually the path to save the downloaded image.
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. Disable webview to load network images and load HTML to display text content first.
To improve the user experience, blocking webview from loading images by itself is a waste of traffic.
First, disable webview to load network images. We can ignore this step because we have replaced the URL in IMG. However, in order to avoid the possibility of leaking the fish, it is better to add:
Webview. getsettings (). setblocknetworkimage (true );
Next, load HTML:
// The result is the parsed HTML text webview. loaddatawithbaseurl (null, result, "text/html", "UTF-8", null );
4. After the text is loaded, download all IMG files to the local device. After each image is downloaded, call the JS Code to refresh the image.
After the text content is loaded, the image content can be loaded. After the HTML content is loaded, the webviewclient. onpagefinished (webview view, string URL) method is called. We can download and save images in this method.
The following code snippet implements the download start function:
Webview. setwebviewclient (New webviewclient () {public void onpagefinished (webview view, string URL) {// downloadwebimgtask is the class used to download images downloadwebimgtask downloadtask = new downloadwebimgtask (); // obtain the urllist of all images <string> urlstrs = parser. getimgurls (); string urlstrarray [] = new string [urlstrs. size () + 1]; urlstrs. toarray (urlstrarray); // starts and downloads downloadtask.exe cute (urlstrarray );}});
The downloadwebimgtask implementation in the above Code is as follows. Its function is to download images in batches and refresh the webview after each image is downloaded. Because webview itself does not provide an interface to refresh images separately (at least I have not found ...), Therefore, this function can only be implemented using Js.
Public class downloadwebimgtask extends asynctask <string, String, void> {public static final string tag = "downloadwebimgtask"; @ overrideprotected void onprogressupdate (string... values) {super. onprogressupdate (values); // load the following JS Code to refresh the webview of a single image. 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);} "+"} "+"}) () ") ;}@ overrideprotected void onpostexecute (void result) {// This Code only ensures that all images are displayed in the 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) ;}@ overrideprotected void doinbackground (string... params) {URL url = NULL; inputstream = NULL; outputstream = NULL; httpurlconnection urlcon = NULL; // If the input parameter is null, if (Params. length = 0) return NULL; file dir = new file (envir Onment. 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 = 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 (); publi Shprogress (urlstr);} catch (malformedurlexception e) {// todo auto-generated catch blocke. printstacktrace ();} catch (ioexception e) {// todo auto-generated catch blocke. printstacktrace ();} finally {try {If (inputstream! = NULL) {inputstream. Close () ;}catch (ioexception E1) {// todo auto-generated catch blocke1.printstacktrace () ;}try {If (outputstream! = NULL) {outputstream. Close () ;}} catch (ioexception e) {// todo auto-generated catch blocke. printstacktrace () ;}} return NULL ;}}
In this way, the image is normally displayed and cached locally.
Finally, a simple demo: http://download.csdn.net/detail/chenshaoyang0011/5130931 is given as an example.