In this section Introduction:

In this section refer to the original: Android 4.4 Precautions .md in WebView

Starting Android 4.4, Android WebView is no longer based on WebKit, but a beginning based on Chromium, this change makes the WebView significantly improved performance, and to HTML5, CSS, JavaScript has better support!

Although chromium completely replaced the previous WebKit for Android, but Android WebView API interface has not changed, it is fully compatible with older versions. Such benefits are based on WebView built APP, without any modifications, will be able to enjoy efficient and powerful chromium kernel.

For the WebView 4.4, we need to note the following issues:


1. Multithreading

If you call related methods WebView in sub-thread, not in the UI thread, it might not be unexpected errors. So, when you need to use the program when multiple threads, please use runOnUiThread () method to ensure that you operate on WebView is carried out in the UI thread:

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

2. The thread blocks

Never block the UI thread, this is a truth to develop Android program. Although the truth is, we are often not consciously make some mistakes go against it, a mistake often made is to develop: the UI thread to wait JavaScript callback. E.g:

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

Do not do it, Android 4.4 provided a new Api to do it. evaluateJavascript () is dedicated to asynchronous execution of JavaScript code.


3.evaluateJavascript() 方法

Designed for asynchronous call JavaScript methods, and can get a callback results.

Example :

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

4. Processing url jump in WebView

The new WebView For custom url scheme of the jump, the new more stringent restrictions. When you achieve a shouldOverrideUrlLoading () or shouldInterceptRequest () callback, WebView will only jump in the jump url is the only legitimate Url. For example, if you use such a url:

<a href="showProfile">Show Profile</a>

shouldOverrideUrlLoading () will not be called.

Correct use is:

<a href="example-app:showProfile">Show Profile</a>

Url jump corresponding detection mode:

// 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;}

当然,也可以这样使用:

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

5.UserAgent变化

如果你的App对应的服务端程序,会根据客户端传来的UserAgent来做不同的事情,那么你需要注意 的是,新版本的WebView中,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.0Mobile Safari/537.36

使用getDefaultUserAgent()方法可以获取默认的UserAgent,也可以通过:

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

来设置和获取自定义的UserAgent。


6.使用addJavascriptInterface()的注意事项

从Android4.2开始。 只有添加 @JavascriptInterface 声明的Java方法才可以被JavaScript调用, 例如:

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

新版的WebView还提供了一个很厉害的功能:使用Chrome来调试你运行在WebView中的程序 具体可以看:remote-debugging PS:需要×××~你也可以直接百度remote-debugging了解相关信息,以及如何使用! 


上一节中N5读取联系人的问题解决:

嘿嘿,看完上面的,我们知道在Android4.2后,只有添加 @JavascriptInterface 声明的Java方法才可以被JavaScript调用,于是乎我们为之前的两个方法加上@JavascriptInterface

但是,加完以后,并没有和我们的预想一样,出现我们想要的联系人列表,这是为什么呢? 我们通过查看Log发现下面这样一段信息:

大概的意思就是:所有的WebView方法都应该在同一个线程程中调用,而这里的contactlist方法却在 JavaBridge线程中被调用了!所以我们要要把contactlist里的东东写到同一个线程中,比如一种解决 方法,就是下面这种:

嘿嘿,接下来运行下程序,神奇的发现,我们N5的手机联系人可以读取到了~

同理,之前第一个示例也可以这样解决


品略图书馆 http://www.pinlue.com/