I am honored if this article has helped you, and sorry if I have wasted your time. I hope to use the simplest plain words to help people like me. If there is any mistake, please do point out, so as not to mislead you, also mislead me. This article from: www.jianshu.com/users/320f9… Thank you for your attention.

WebView is used very often in current projects. I personally have always felt that HTML5 is a trend. I found a few things and summarized them here. At the end of this article, there is a very nice Html5Activity loading class. If you don’t want to see it, you can download it directly.

WebSettings

WebSettings webSettings = mWebView .getSettings(); / / support for gestures, enter the user name, password, or other webview. RequestFocusFromTouch (); setJavaScriptEnabled(true); // Support js setPluginsEnabled(true); / / support plug-in webSettings. SetRenderPriority (RenderPriority. HIGH); SetUseWideViewPort (true); SetLoadWithOverviewMode (true); // Zoom to the size of the screen setSupportZoom(true); // Supports scaling and defaults to true. That's the premise of the following one. setBuiltInZoomControls(true); // setDisplayZoomControls can be scaled (false); // Hide the native zoom control // If the above is false, the WebView is not scalable, and this will not scale regardless of what is set. setTextZoom(2); SetLayoutAlgorithm (LayoutAlgorithm.SINGLE_COLUMN); // Support content relayout supportMultipleWindows(); // multi-window setCacheMode(websettings. LOAD_CACHE_ELSE_NETWORK); // Turn off setAllowFileAccess(true); // Set the file to be accessible setNeedInitialFocus(true); / / when the webview call requestFocus set node for the webview setJavaScriptCanOpenWindowsAutomatically (true); / / support by JS setLoadsImagesAutomatically open a new window (true); / / support automatic loading setDefaultTextEncodingName images (" utf-8 "); // set the encoding format setStandardFontFamily(""); // Set the WebView font, default font is "sans-serif" setDefaultFontSize(20); // Set the WebView font size. The default size is 16 setMinimumFontSize(12); // Set the minimum font size supported by WebView. The default is 8Copy the code


About the cache

##### Cache mode LOAD_CACHE_ONLY: no network is used but only local cache data is read LOAD_DEFAULT: (default) Determines whether to fetch data from the network based on cache-control. LOAD_NO_CACHE: does not use the cache and only gets data from the network. LOAD_CACHE_ELSE_NETWORK, as long as it is locally available, regardless of expiration, or no-cache, uses the data in the cache.

Combined use (offline loading) :

if (NetStatusUtil.isConnected(getApplicationContext())) { webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); Cache-control determines whether to fetch data from the network. } else { webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); / / not network, from a local, or off-line load} webSettings. SetDomStorageEnabled (true); / / open the DOM storage API function webSettings setDatabaseEnabled (true); / / open the database storage API function webSettings. SetAppCacheEnabled (true); String cacheDirPath = getFilesDir().getabsolutePath () + APP_CACAHE_DIRNAME; // Enable Application Caches. webSettings.setAppCachePath(cacheDirPath); // Sets the Application Caches cache directoryCopy the code

Note: each Application. Just call a WebSettings setAppCachePath (), WebSettings. SetAppCacheMaxSize ()


Loading way

Load a web page: webview.loadurl (“www.google.com/”); Load an HTML page in the apk package webview.loadurl (“file:///android_asset/test.html”); Load cell phone local method of an HTML page: the webView. LoadUrl (” content: / / com. Android. Htmlfileprovider/sdcard/test. The HTML “);

Add HTTP request Headers

loadUrl(String url, Map<String, String> additionalHttpHeaders)


WebViewClient

WebViewClient helps webViews handle notifications and requests. Instead of calling the system browser when opening the web page, it will display in this WebView:

mWebView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; }});Copy the code

WebViewClient method

WebViewClient mWebViewClient = new WebViewClient() {shouldOverrideUrlLoading(WebView view, String URL) // All loads on the page go through this method. We can do a lot of things with this function. ShouldOverrideKeyEvent (WebView view, KeyEvent event) shouldOverrideKeyEvent(WebView view, KeyEvent event) // Override this method to handle keystroke events in the browser. OnPageStarted (WebView View, String URL, Bitmap Favicon) onPageStarted(WebView View, String URL, Bitmap Favicon) onPageStarted(WebView View, String URL, Bitmap Favicon) OnPageFinished (WebView View, String URL) // Called at the end of page loading. In the same way, we can turn off the loading bar to switch program actions. OnLoadResource (WebView view, String URL) // Called when page resources are loaded, once for each resource (such as images) loaded. ShouldInterceptRequest (WebView view, String URL); ShouldInterceptRequest (WebView View, WebResourceRequest Request); OnReceivedError (WebView View, int errorCode, String Description, String failingUrl) // (error message reported) doUpdateVisitedHistory(WebView view, String URL, Boolean isReload) //(update history) onFormResubmission(WebView view, Message dontResend, Message resend) / / (application) to request web data onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host,String realm) // (Authorization request to obtain returned information) onReceivedSslError(WebView view, SslErrorHandler Handler, SslError error) // Override this method to make the WebView handle HTTPS requests. OnScaleChanged (WebView view, float oldScale, float newScale) onUnhandledKeyEvent(WebView view, float newScale) KeyEvent event) // (called when the Key event is not loaded)}Copy the code

Set the WebViewClient defined above to WebView:

  webView.setWebViewClient(mWebViewClient);
Copy the code


WebChromeClient

WebChromeClient helps WebView handle Javascript dialog boxes, site ICONS, site titles, loading progress, etc. : the code in the method is handled by the Android side itself.

WebChromeClient mWebChromeClient = new WebChromeClient() {// Get the page loading progress, @override public void onProgressChanged(WebView view, int newProgress) { if (newProgress < 100) { String progress = newProgress + "%"; } else {}} // Get the title of the Web page to set the title of your interface. // If there is a loading error, such as no network, then the title of the onReceiveTitle is not found. Don't use to get the title @ Override public void onReceivedTitle (WebView view, String title) {MainActivity. This. SetTitle (title); } @Override public void onReceivedIcon(WebView view, Bitmap icon) { // } @Override public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { // return true; } @override public void onCloseWindow(WebView window) { @override public Boolean onJsAlert(WebView view, String URL, String message, JsResult result) { // return true; @override public Boolean onJsPrompt(WebView view, String URL, String message, String defaultValue, JsPromptResult result) { // return true; @override public Boolean onJsConfirm(WebView view, String URL, String message, JsResult result) { // return true; }};Copy the code

Also, set the WebChromeClient defined above to the WebView:

  webView.setWebChromeClient(mWebChromeClient);
Copy the code


Some methods of WebView

Forward and backward

GoBackOrForward (intSteps) goBackOrForward(intSteps) goBack() goBackOrForward(intSteps) goBackOrForward(intSteps) The positive number is forward canGoForward()// canGoBack() // canGoBackCopy the code

Clear cached data:

clearCache(true); ClearHistory () clears the history of the current webView visit, ClearFormData ()// This API clears only auto-populated form data, not webView data stored locally.Copy the code

WebView state:

OnPause ()// If the page loses focus and is switched to an invisible state in the background, you need to perform onPause. The onPause action tells the kernel to pause all actions. For example, DOM parsing, plugin execution, JavaScript execution. PauseTimers ()// When the application was switched to the background, we used the WebView. This method was not only for the current webview, but for the whole application of the webView, and it paused the layout, parsing, of all webviews. Javascripttimer. Reduce CPU power consumption. ResumeTimers ()// Action for resuming pauseTimers. Destroy ()// Destroy, the music or video is still playing when the Activity is closed. It has to be destroyed.Copy the code

Note, however, that when webView calls DeStory, the WebView is still tied to the Activity. This is because the Activity context is passed in when the custom WebView is built, so we need to remove the WebView from the parent container and then destroy the webView:

  rootLayout.removeView(webView);
  webView.destroy();
Copy the code

Check whether the WebView has rolled to the bottom or top of the page: The getScrollY() // method returns the distance between the top of the current visible area and the top of the page, which is how far the current content is scrolling. Both getHeight() and getBottom() // return the height of the current WebView container GetContentHeight () returns the height of the entire HTML, but not the current height of the entire page, because WebView has scaling, so the current height of the entire page should actually be the height of the original HTML multiplied by the scaling scale. Therefore, after correction, the accurate judgment method should be:

If (webview.getScale () == (webView.getheight () + webView.getScrolly ())) {// Currently at the bottom} If (webView.getScrolly () == 0){// at the top}Copy the code


Return key

Returns to the last page viewed

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
        mWebView.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
Copy the code


Calling JS code

  WebSettings webSettings = mWebView .getSettings();
  webSettings.setJavaScriptEnabled(true);

  mWebView.addJavascriptInterface(new InsertObj(), "jsObj");
Copy the code

This is the premise!! We then implement the above class, which provides four methods and is clearly commented out.

Class InsertObj extends Object {/ / method for HTML, js can through: var STR = window. JsObj. HtmlcallJava (); @javascriptInterface public String HtmlcallJava() {return "Html callJava "; } / / to have reference function provided by the HTML: window. JsObj. HtmlcallJava2 (" IT - Homer Simpson blog "); @JavascriptInterface public String HtmlcallJava2(final String param) { return "Html call Java : " + param; } @javascriptInterface public void JavacallHtml() {runOnUiThread(new Runnable() {@override public void JavacallHtml() Run () {// here is the call method mwebView.loadurl ("javascript: showFromHtml()"); Toast.makeText(Html5Activity.this, "clickBtn", Toast.LENGTH_SHORT).show(); }}); } @javascriptInterface public void JavacallHtml2(final String param) {runOnUiThread(new Runnable() { @Override public void run() { mWebView.loadUrl("javascript: showFromHtml2('IT-homer blog')"); Toast.makeText(Html5Activity.this, "clickBtn2", Toast.LENGTH_SHORT).show(); }}); }}Copy the code

There is a leak Android called js: blog.csdn.net/leehong2005…


1. Add listening to WebView
mWebview.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {

    }
});
Copy the code
2. Get the clicked picture address

First get the type, according to the corresponding type to process the corresponding data.

  1. First determine the type of click
	WebView.HitTestResult result = ((WebView) v).getHitTestResult();
	int type = result.getType();
Copy the code

There are several types of type: WebView. HitTestResult. UNKNOWN_TYPE unknown type WebView. HitTestResult. PHONE_TYPE phone type WebView. HitTestResult. EMAIL_TYPE email type WebView. HitTestResult. GEO_TYPE map type WebView. HitTestResult. SRC_ANCHOR_TYPE hyperlink type WebView. HitTestResult. SRC_IMAGE_ANCHOR_TYPE with link picture type WebView. The HitTestResult. IMAGE_TYPE simple image type WebView. HitTestResult. EDIT_TEXT_TYPE selected text types

  1. To get specific information, the picture here is the picture address
	String imgurl = result.getExtra();
Copy the code
3. Manipulate pictures

You can pop up to save the image, or click to go to the page that shows the image.

A final tidbit of code:

mWebView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { WebView.HitTestResult result = ((WebView)v).getHitTestResult(); if (null == result) return false; int type = result.getType(); if (type == WebView.HitTestResult.UNKNOWN_TYPE) return false; / / here can intercept many types, we can deal only with the picture type is the switch (type) {case WebView. HitTestResult. PHONE_TYPE: / / processing dial-up break; Case WebView. HitTestResult. EMAIL_TYPE: / / processing Email break; Case WebView. HitTestResult. GEO_TYPE: / / map type break; Case WebView. HitTestResult. SRC_ANCHOR_TYPE: / / link break; case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE: break; Case WebView. HitTestResult. IMAGE_TYPE: / / processing according to the menu item of the picture/long/get photo path String saveImgUrl = result. GetExtra (); Intent I = new Intent(mainactivity.this, imageactivity.class); i.putExtra("imgUrl", saveImgUrl); startActivity(i); break; default: break; }}});Copy the code


Android5.0 WebView Http and Https mixing problems

On Android 5.0, Webview does not allow loading mixed Http and Https content by default:

Solutions:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
     webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
Copy the code

Parameter Type Description: MIXED_CONTENT_ALWAYS_ALLOW: allows content to be loaded from any source, even if the origin is unsafe. MIXED_CONTENT_NEVER_ALLOW: Https is not allowed to load Http content, that is, it is not allowed to load an unsafe resource from a secure source. MIXED_CONTENT_COMPATIBILITY_MODE: WebView tries to be compatible with the latest Web browser styles when it comes to hybrid content.

Android allows all web pages below 5.0 by default, but does not allow all web pages above 5.0. In practice, it is very difficult to confirm that all web pages are HTTPS, so this step is required.

Set WebView to accept certificates from all web sites


Cookie related

The CookieSyncManager class used to synchronize cookies has been deprecated. WebView can now automatically synchronize cookies when needed, so there is no need to create objects of the CookieSyncManager class to do mandatory cookie synchronization. Now you just need to get the CookieManager object and set the cookie in it.

Obtain the cookie from the return header of the server. The method of obtaining the cookie varies according to the clients that request Http.

1. The client sets the cookie through the following code. If the two Settings are the same, the last one will be overwritten.
/** * Set the cookie to WebView * @param URL to load * @param cookie to synchronize cookie */ public static void syncCookie(String) url,String cookie) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { CookieSyncManager.createInstance(context); } CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setCookie(url, cookie); // If there is no special requirement, the session id should be "key=value" as the cookie.Copy the code

Note:

  1. Cookies should be synchronized before the WebView loads the URL, otherwise the WebView cannot get the corresponding cookie and cannot pass the authentication.
  2. Cookies should be updated in a timely manner, otherwise the WebView is likely to use the old session ID to communicate with the server.
2. CookieManager stores the Cookie in the application data/data/package_name/app_WebView/Cookies
3. Open the web page, WebView reads the cookie value from the database, puts it in the header of the HTTP request, and passes it to the server
Public static String syncCookie(String URL) {CookieManager CookieManager = CookieManager.getInstance(); return cookieManager.getCookie(url); }Copy the code
4. Clear cookies:
/ / the two at the API level 21 abandoned CookieManager. GetInstance (). RemoveSessionCookie (); CookieManager.getInstance().removeAllCookie(); / / it is recommended to use these two, level 21 new CookieManager. GetInstance () removeSessionCookies (); / / remove all expired cookies CookieManager. GetInstance () removeAllCookies (); // Remove all cookiesCopy the code


private void removeCookie(Context context) { CookieManager.getInstance().removeAllCookies(new ValueCallback<Boolean>() { @override public void onReceiveValue(Boolean value) {// Clear result}}); }Copy the code


Some ways to avoid WebView memory leaks

1. You can start a new Webview Activity and end it with system.exit (0); Exit the current process. Start a new process, the main code: Androidmanifest.xml configuration file code is as follows

    <activity
        android:name=".ui.activity.Html5Activity"
        android:process=":lyl.boon.process.web">
        <intent-filter>
            <action android:name="com.lyl.boon.ui.activity.htmlactivity"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>
Copy the code

Start the Activity in a new process and pass in a Url:

    Intent intent = new Intent("com.lyl.boon.ui.activity.htmlactivity");
    Bundle bundle = new Bundle();
    bundle.putString("url", gankDataEntity.getUrl());
    intent.putExtra("bundle",bundle);
    startActivity(intent);
Copy the code

Then add system.exit (0) to the end of the onDestory() of Html5Activity; Kill the current process.

2. You can’t define webViews in XML. Instead, you can create webViews as needed, and the Context uses getApplicationgContext().

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mWebView = new WebView(getApplicationContext());
        mWebView.setLayoutParams(params);
        mLayout.addView(mWebView);
Copy the code

3. During Activity destruction, you can have the WebView load null content first, then remove the WebView, then destroy the WebView, and finally empty it. The code is as follows:

@Override protected void onDestroy() { if (mWebView ! = null) { mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); mWebView.clearHistory(); ((ViewGroup) mWebView.getParent()).removeView(mWebView); mWebView.destroy(); mWebView = null; } super.onDestroy(); }Copy the code





There is a nice Html5Activity loading class posted:

package com.lyl.web; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.KeyEvent; import android.webkit.GeolocationPermissions; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import com.lyl.test.R; public class Html5Activity extends AppCompatActivity { private String mUrl; private LinearLayout mLayout; private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web); Bundle bundle = getIntent().getBundleExtra("bundle"); mUrl = bundle.getString("url"); Log.d("Url:", mUrl); mLayout = (LinearLayout) findViewById(R.id.web_layout); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); mWebView = new WebView(getApplicationContext()); mWebView.setLayoutParams(params); mLayout.addView(mWebView); WebSettings mWebSettings = mWebView.getSettings(); mWebSettings.setSupportZoom(true); mWebSettings.setLoadWithOverviewMode(true); mWebSettings.setUseWideViewPort(true); mWebSettings.setDefaultTextEncodingName("utf-8"); mWebSettings.setLoadsImagesAutomatically(true); // Call the JS method. The android version is more than 17, annotated @ JavascriptInterface mWebSettings. SetJavaScriptEnabled (true); saveData(mWebSettings); newWin(mWebSettings); mWebView.setWebChromeClient(webChromeClient); mWebView.setWebViewClient(webViewClient); mWebView.loadUrl(mUrl); } @Override public void onPause() { super.onPause(); webView.onPause(); webView.pauseTimers(); // Watch out for this!! Pause all layout, parsing, and JS throughout the WebView. } @Override public void onResume() { super.onResume(); webView.onResume(); webView.resumeTimers(); Private void newWin(WebSettings mWebSettings) {private void newWin(WebSettings mWebSettings) {private void newWin(WebSettings mWebSettings) { Need to be / / then autotype WebChromeClient onCreateWindow method under mWebSettings. SetSupportMultipleWindows (false); mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true); } /** * HTML5 data store */ private void saveData(WebSettings mWebSettings) {// Sometimes the web needs to save some key data,Android WebView needs to set itself mWebSettings.setDomStorageEnabled(true); mWebSettings.setDatabaseEnabled(true); mWebSettings.setAppCacheEnabled(true); String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath(); mWebSettings.setAppCachePath(appCachePath); } WebViewClient WebViewClient = new WebViewClient(){** * multiple pages open in the same WebView, Public Boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; }}; WebChromeClient webChromeClient = new WebChromeClient() { / / = = = = = = = = = it locate = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = / / need to add permissions / / < first USES - the permission android:name="android.permission.INTERNET"/> //<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>  //<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> @Override public void onReceivedIcon(WebView view, Bitmap icon) { super.onReceivedIcon(view, icon); } @Override public void onGeolocationPermissionsHidePrompt() { super.onGeolocationPermissionsHidePrompt(); } @Override public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) { callback.invoke(origin, true, false); / / pay attention to the function, the second parameter is agree with location permissions, the third is whether you want to the kernel remember super onGeolocationPermissionsShowPrompt (origin, callback); } / / = = = = = = = = = it locate = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = / / = = = = = = = = = more window problem = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = @ Override public Boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; transport.setWebView(view); resultMsg.sendToTarget(); return true; } / / = = = = = = = = = more window problem = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =}; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) { mWebView.goBack(); return true; } return super.onKeyDown(keyCode, event); } @Override protected void onDestroy() { super.onDestroy(); if (mWebView ! = null) { mWebView.clearHistory(); ((ViewGroup) mWebView.getParent()).removeView(mWebView); mWebView.loadUrl("about:blank"); mWebView.stopLoading(); mWebView.setWebChromeClient(null); mWebView.setWebViewClient(null); mWebView.destroy(); mWebView = null; }}}Copy the code

Forgive me, forget from where, if infringement please contact me, must delete.




(a) 【 Webview cookie mechanism 】 easy to fix the webview cookie synchronization problem there are some scattered links.