Some considerations for WebView after Android 4.4


Introduction to this section:

Reference to the original text for this section: Precautions for using WebView in Android 4.4.md

Starting from Android 4.4, WebView in Android is no longer based on WebKit, but begins to be based on Chromium. This change The performance of WebView has been greatly improved, and it has better support for HTML5, CSS, and JavaScript!

Although chromium completely replaced the previous WebKit for Android, the API interface of Android WebView has not changed. Fully compatible with older versions. The advantage of this is that the APP built based on WebView does not require any modification. You can enjoy the efficiency and power of the chromium core.

For WebView after 4.4, we need to pay attention to the following issues:


1. Multi-threading

If you are in a child thread If you call the relevant methods of WebView in the UI thread instead of the UI thread, unpredictable errors may occur. Therefore, when you need to use multi-threading in your program, please also use the runOnUiThread() method to ensure that you WebView operations are performed in the UI thread:

runOnUiThread(newRunnable(){
@Override
publicvoid run(){
   // Code for WebView goes here
   }
});

2. Thread blocking

Never block the UI thread, this is one of the first steps in developing Android programs truth. Although it is the truth, we often do not realize it Make some mistakes that go against it. A common mistake in development is waiting for JavaScript callbacks in the UI thread. For example:

// This code is BAD and will block the UI thread
webView.loadUrl("javascript:fn()"); 
while(result ==null) {  
    Thread.sleep(100); 
}

Don’t do this. Android 4.4 provides a new API to do this. evaluateJavascript() is specifically designed to execute JavaScript code asynchronously.


3.evaluateJavascript() method

is specially used to call JavaScript methods asynchronously and can get a callback result.

Example:

mWebView.evaluateJavascript(script, new ValueCallback() {
 @Override
 public void onReceiveValue(String value) {
      //TODO
 }
});

4. Handle the jump of url in WebView

The new version of WebView is for customization The URL jump of scheme has new stricter restrictions. When you implement shouldOverrideUrlLoading() or shouldInterceptRequest() callbacks, WebView will only jump when the jump URL is a legal URL. For example, if you use a url like this:

Show Profile

shouldOverrideUrlLoading() will not be called.

The correct way to use it is:

Show Profile

The corresponding way to detect Url jump:

// The URL scheme should be non-hierarchical (no trailing slashes)
 privatestaticfinalString APP_SCHEME ="example-app:";
 @Override 
 publicboolean shouldOverrideUrlLoading(WebView view,String url){
     if(url.startsWith(APP_SCHEME)){
         urlData =URLDecoder.decode(url.substring(APP_SCHEME.length()),"UTF-8");
         respondToData(urlData);
         returntrue;
     }
     returnfalse;
}

Of course, it can also be used like this:

webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA,null,"UTF-8",null);

5.UserAgent changes

If the server program corresponding to your App will do different things based on the UserAgent sent from the client, then you need to pay attention What's more, in the new version of WebView, there are some subtle changes in UserAgent:

Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16H)
AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0
Mobile Safari/537.36

Use the getDefaultUserAgent() method to get the default UserAgent, or you can pass:

mWebView.getSettings().setUserAgentString(ua);
mWebView.getSettings().getUserAgentString();

To set and get a custom UserAgent.


6. Notes on using addJavascriptInterface()

Starting from Android 4.2. Only Java methods declared with @JavascriptInterface can be called by JavaScript. For example:

class JsObject {
    @JavascriptInterface
    public String toString() { return "injectedObject"; }
}

webView.addJavascriptInterface(new JsObject(), "injectedObject");
webView.loadData("", "text/html", null);
webView.loadUrl("javascript:alert(injectedObject.toString())");

7.Remote Debugging

1.png

The new version of WebView also provides a very powerful function: use Chrome to debug your program running in WebView For details, please see: remote-debugging PS: You need a ladder~ You can also directly Baidu remote-debugging to learn about relevant information and how to use it!


Solution to the problem of N5 reading contacts in the previous section:

Hey, after reading the above, we know that after Android 4.2, only Add @JavascriptInterface Only declared Java methods can be called by JavaScript, so we added @JavascriptInterface

2.png

to the previous two methods. However, after adding it, there was no As we expected, the contact list we want appears. Why is this? By looking at the Log, we found the following piece of information:

5.png

The general meaning is: all WebView methods should be called in the same thread, but the contactlist method here is exist Was called in the JavaBridge thread! So we need to write the stuff in the contactlist into the same thread, such as a solution The method is as follows:

3.png

Hey, let’s run the program and magically find that our N5’s mobile phone contacts can be read~

4.png

Similarly, the first example before can also be solved in this way~


Summary of this section:

Follow everyone in this section A trip to the things to pay attention to in WebView after Android 4.4, as well as some answers to the N5 issues in the previous section The solution ~ I believe it will bring convenience to everyone in using WebView in actual development ~ Thank you