There is a high-performance WebKit kernel browser built into Android phones, which is packaged in the SDK as a component called WebView. Here’s a summary of the pitfalls of using WebView.

directory

First, the basic use of WebView

Webview and JS interaction (attached sample project complete source code)

Android calls JS functions with parameters and no return value. Android calls JS functions with parameters and no return value. Android calls JS functions with parameters and return value (before 4.4). Get a web page image to enlarge

3, WebView encountered those pits and solutions **

First, the basic use of WebView

1. Add permissions: AndroidManifest. Set the permissions on the XML in the android. Permission. “the INTERNET”, otherwise will be out of the Web page not available error.

2. Create a WebView component in your Activity: WebView WebView = new WebView(this); You can also add a WebView control to the Activity layout file

3. Set basic WebView information:

mWebView = (WebView) findViewById(R.id.wb); mWebView.getSettings().setJavaScriptEnabled(true); // Support javascript mwebView.requestFocus (); / / touch focus work mWebView. SetScrollBarStyle (WebView. SCROLLBARS_OUTSIDE_OVERLAY); / / cancel the scrollbar mWebView getSettings () setJavaScriptCanOpenWindowsAutomatically (true); //load local mwebview. loadUrl("file:///android_asset/hellotest.html"); / / load/online/mWebView loadUrl (" http://www.google.com "); Visit android / / js, defining interfaces mWebView. AddJavascriptInterface (new JsInteration (), "control"); // If Alert is set, OnJsAlert again () method to return true can customize the process information mWebView. SetWebChromeClient (new WebChromeClient () {@ Override public Boolean onJsAlert(WebView view, String url, String message, JsResult result) { //return super.onJsAlert(view, url, message, result); Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show(); return true; }});Copy the code

4. Set WevView to display a web page: webview.loadurl (“www.google.com”); LoadUrl (“file:///android_asset/XX.html”); Local files are stored in: assets

5. If you want to click the link by yourself, instead of responding to the link in browser, the new Android system. Add an event listener to the WebView (WebViewClient) and rewrite some of the methods: shouldOverrideUrlLoading: a response to a hyperlink button in a web page. The WebViewClient calls this method when a connection is pressed, passing the parameters

public boolean shouldOverrideUrlLoading(WebView view,String url){
       view.loadUrl(url);
       return true;          
        }Copy the code

6. Processing HTTPS requests The webView does not process HTTPS requests by default. The webView page is blank.

webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); // handler.cancel(); // handler.handleMessage(null); }}); OnReceivedSslError handles SSL certificate Settings for webViewCopy the code

The handler. Proceed (); Wait for the certificate to respond handler.cancel(); Handler. handleMessage(null); You can do other things and there are other methods that you can override 1, Receives the Http request events onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm) 2, Public void onPageFinished(WebView View, String URL){} In the same way, we know that a page is finished loading, so we can close the loading bar and switch the program action. Public void onPageStarted(WebView view, String URL, Bitmap Favicon) {} Usually we can set a loading page here to tell the user that the application is waiting for a network response. Through these several events, we can easily control the program operation, while using the browser to display the content, while monitoring the user operation to achieve the various display we need, at the same time can prevent the user from misoperation.

7. If you click the webView link to view many pages without doing anything, click the system “Back” button, and the browser calls Finish () to finish itself. If you want the page to go Back instead of exiting the browser, you need to process and consume the Back event in the current Activity. Override the onKeyDown(int keyCoder,KeyEvent Event) method of the Activity class.

@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) { webView.goBack(); // Return true; } return super.onKeyDown(keyCode, event); }Copy the code

Ii. Interaction between WebView and JS (call parameters and pass values)

Front-end web page code, the end of the article has sample project complete source code

Jaydenxiao encountered webView JS accessing android methodsCopy the code

Call example:

Js invokes the Java

Call format for Windows. JsInterfaceName. MethodName (parameterValues) in this case we use the control as the interface name.

function toastMessage(message) { 
window.control.toastMessage(message) 
}
 function sumToJava(number1, number2){ 
window.control.onSumResult(number1 + number2)
 }Copy the code
Java calls JS

LoadUrl (” javascript:methodName(parameterValues) “) 1. Android calls js functions with no parameters and no return value

final String call = "javascript:sayHello()";
mWebView.post(new Runnable() {    
@Override    
public void run() { 
       mWebView.loadUrl(call);    
}});Copy the code

2. Android calls js functions with arguments and no return value

Final String call = "javascript:alertMessage(\"" + "HEY man" + "\")"; mWebView.post(new Runnable() { @Override public void run() { mWebView.loadUrl(call); }});Copy the code

Before 4.4, Android did not provide a method to directly call JS functions and get values, so before this, the common idea is Java to call JS methods, js method execution, call Java code to return values. (1). Android calls JS code

Final String call = "javascript:sumToJava(1,2)"; mWebView.post( new Runnable() { @Override public void run() { mWebView.loadUrl(call); }});Copy the code

(2).js function and return the result to the webpage by calling the Android method:

function sumToJava(number1, number2){ 
window.control.onSumResult(number1 + number2) 
}Copy the code

(3). Android gets the return value of the JS function in the callback method

@JavascriptInterfacepublic void onSumResult(int result) { Toast.makeText(getApplicationContext(), + result, toast.length_long).show(); }Copy the code

EvaluateJavascript: evaluateJavascript: evaluateJavascript: evaluateJavascript: evaluateJavascript: evaluateJavascript Here is a simple interactive example of a js method with a return value:

function sumToJava2(number1, number2) {
return number1 + number2;
}Copy the code

The Android code is as follows:

@TargetApi(Build.VERSION_CODES.KITKAT) public void Android2JsHaveParmHaveResult2(View view) { MWebView. EvaluateJavascript (" sumToJava2 (3, 4) ", new ValueCallback() { @Override public void onReceiveValue(String Str) { Toast.makeText(getApplicationContext(), + Str, toast.length_long).show(); }}); }Copy the code

3, WebView encountered those pits and solutions

1. WebView memory leaks. This problem is hard to describe clearly. If you search WebView lead Memory in Google, you can find many results and even issue submitted to Google. Haha, I can’t give a clear answer on when and what version those phones will definitely have memory leaks. However, according to some monkey results, sometimes webView memory leaks can be quite serious, especially if you load large pages. When you want to use webView, remember to open a separate process to use webView and when this process ends, please manually call system.exit (0). This is by far the best solution for webView memory leaks. Using this method, all the problems caused by webView can be solved.

2. GetSettings ().setBuiltinzoomControls (true) trigger crush. After this method is called, if you touch the screen and the box doesn’t disappear, you’ll get an error if your activity ends. In order to avoid this problem, we will manually set webiew to setVisibility(view.gone) in the activity onDestroy method.

3. Is the onPageFinished function useful? Most developers are reference stackoverflow.com/questions/3… The big answer on this one. In fact, according to my own observation, this function is not very useful, sometimes it ends early, sometimes it doesn’t end late, you should trust god in this function, even onProgressChanged is more accurate than onPageFinished. If your product manager insists that you implement this feature, I suggest you end it early, otherwise it’s not a good experience to be stuck. If you have time, you can look at the source code. OnPageFinished is called at different times in different kernels. To be honest, I’m drunk too… Please let me know if there is a perfect solution to this problem…

4. The background fails to release JS, resulting in power consumption. This is probably not very well known, but if you have a WebView that’s loading HTML with js that’s executing something like an animation or something like that, and if the WebView is hanging in the background at the moment those resources won’t be released, and the user won’t be able to sense it, so it’s always occupying the CPU and consuming power very quickly, so remember, SetJavaScriptEnabled () in onStop and onResume; Set to false and true.

5. If you really don’t want to open extra processes to solve the webView memory leak problem, then the following method can largely avoid this situation

public void releaseAllWebViewCallback() { if (android.os.Build.VERSION.SDK_INT < 16) { try { Field field = WebView.class.getDeclaredField("mWebViewCore"); field = field.getType().getDeclaredField("mBrowserFrame"); field = field.getType().getDeclaredField("sConfigCallback"); field.setAccessible(true); field.set(null, null); } catch (NoSuchFieldException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } } catch (IllegalAccessException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } } } else { try { Field sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback"); if (sConfigCallback ! = null) { sConfigCallback.setAccessible(true); sConfigCallback.set(null, null); } } catch (NoSuchFieldException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } } catch (ClassNotFoundException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } } catch (IllegalAccessException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); }}}}Copy the code

Just call this method in the Destroy method of the WebView.

Finally, the sample source code is attached. Welcome to fork and Star