postUrl and loadUrl of Android Webview load page instances

  • 2021-11-30 01:26:28
  • OfStack

As for webview of Android, it must be familiar to use it. Here I will not say the basic usage of webview, want to know can go to the Internet more than 100, there are a lot of basic usage of webview.

This article will mainly introduce the pits encountered in using postUrl of webview during the project.

1. The usage scenario is as follows:

When webview loads H5 link, it uses loadUrl by default. If you set the cache attribute (caching), click to jump to another page in the displayed H5 page, and press the back key to return to the previous page normally because of the cache setting. However, if you use postUrl to load, even if the cache attribute you set is set, when you switch to another page, press the back key, which will not cache the previous page, but call postUrl again to load. At this time, the problem comes, which is also loaded. The first postUrl can be loaded normally, and reloading will fail, and there is no content displayed. Isn't it interesting? Why does this happen? By grasping the package, it is found that although the same link is loaded, the reloaded request attribute is empty, which leads to the loading failure.

2. How to solve:

Now that the reason is found and the request property is empty, there must be a solution, so set the request property manually and reload it. How to set it manually, first of all, you must be able to get all the contents and parameters of the request. Anyone who has used webview must be familiar with its setWebViewClient method. The shouldInterceptRequest method inside this method can get all the contents of the request. Not much to say, first on the code.


public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
  if(Build.VERSION.SDK_INT >= 21){
   if(!request.getMethod().equalsIgnoreCase("post")){
    return super.shouldInterceptRequest(view, request);
   }
  }
  DataOutputStream os = null;
  try {
   URL mUrl = new URL(url);
   HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
   connection.setDoInput(true);
   connection.setDoOutput(true);
   connection.setUseCaches(false);
   connection.setRequestMethod("POST");
   if(Build.VERSION.SDK_INT >= 21){
    Iterator headerKeys=request.getRequestHeaders().keySet().iterator();
    while(headerKeys.hasNext()){
     String key=headerKeys.next();
     connection.setRequestProperty(key,request.getRequestHeaders().get(key));
    }
   }
   connection.setRequestProperty("content-type","application/x-www-form-urlencoded");
   os = new DataOutputStream(connection.getOutputStream());
 
   os.write(EncodingUtils.getBytes(postData, "BASE64"));
   os.flush();
   return new WebResourceResponse("text/html", connection.getContentEncoding(), connection.getInputStream());
  } catch (Exception e) {
   e.printStackTrace();
  }finally {
   if(os!=null){
    try {
     os.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
  return super.shouldInterceptRequest(view, request);
 }
});

webView.postUrl(url, EncodingUtils.getBytes(postData, "BASE64"));

This method has a defect, which is only available in Api above Android 5.0. 0, and Api below 5.0. 0 does not have this method, which is also a pit and cannot be compatible with all models. Reset the request property by setRequestProperty method in this method, and then use postUrl to reload, which can solve the problem of page restoration after pressing the back key. Note that since post loads cannot be cached, 1 must be set to the reload property when setting the cache property.

3. Problems after solving:

The problem seems to be solved, but this method will have pits. If you study this method carefully, you will find that the shouldInterceptRequest method is called throughout the load. If you grab packets, you will find that this method will be called for every request loaded from the beginning of loading links to H5 pages. Simply put, this method will be called as many times as there are requests. If there is another post request in your page, then the problem comes. You need to compare the request content of the second post request with the first one, and choose whether to load the first page or the second page after comparison, otherwise the first post page will be loaded by default.

4. Conclusion

loadUrl is the best way to load H5 pages of webview. If postUrl is used, you need to rewrite the whole setWebViewClient method, which will make many pits. This is not recommended.


Related articles: