This is a comprehensive & detailed introduction to the use of Webview for Android

Posted by marque on Mon, 03 Jan 2022 03:20:38 +0100

preface

  • Many apps now have built-in Web pages (Hyprid App), such as many e-commerce platforms, such as Taobao, JD, Jubi, etc., as shown in the following figure

  • So how can this be achieved? In fact, this is implemented by a component called WebView in Android. Today I'll give a comprehensive introduction to the common uses of WebView.

catalogue

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-sntzdrbr-1640421131904)( https://p1-jj.byteimg.com/tos...)]

1. Introduction

WebView is a web page control based on webkit engine.

Webview of Android adopts different webkit versions and kernels in the lower and higher versions, and Chrome is directly used after 4.4.

2. Function

  • Displaying and rendering Web pages
  • Directly use html files (on the network or in local assets) for layout
  • It can be called interactively with JavaScript

WebView control is powerful. In addition to general View properties and settings, it can also handle url requests, page loading, rendering and page interaction.

3. Introduction to use

Generally speaking, Webview can be used alone or in combination with its subclasses, so next, I will introduce:

  • Common methods of Webview itself;
  • The most commonly used subclasses of Webview (WebSettings class, WebViewClient class, WebChromeClient class)
  • Interaction between Android and Js

3.1 common methods of WebView

3.1. 1 load url

There are three loading methods according to resources

  //Mode 1 Load a web page:
  webView.loadUrl("http://www.google.com/");

  //Method 2: load the html page in apk package
  webView.loadUrl("file:///android_asset/test.html");

  //Method 3: load the local html page of the mobile phone
   webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");

   // Method 4: load a small section of HTML page
  WebView.loadData(String data, String mimeType, String encoding)
// Parameter Description:
// Parameter 1: the displayed content needs to be intercepted
// '#', '%', '\', '?' cannot appear in the content If these four characters appear, they should be replaced by% 23,% 25,% 27,% 3F. Otherwise, exceptions will occur
// Parameter 2: display content type
// Parameter 3: bytecode


3.1. 1. Status of WebView

//Activate WebView to be active, and the response of the web page can be executed normally
webView.onResume() ;

//When the page is out of focus and switched to the invisible state in the background, onPause needs to be executed
//The onPause action informs the kernel to suspend all actions, such as DOM parsing, plugin execution, and JavaScript execution.
webView.onPause();

//When the application (existing webview) is switched to the background, this method is not only for the current webview, but also for the global application wide webview
//It will pause the layout, parsing and JavaScript timer of all webview s. Reduce CPU power consumption.
webView.pauseTimers()
//Restore pauseTimers state
webView.resumeTimers();

//Destroy Webview
//When the Activity is closed, if the music or video of Webview is still playing. You must destroy the Webview
//But note: when webview calls destory, webview is still bound to Activity
//This is because the context object of the Activity is passed in when the custom webview is built
//Therefore, you need to remove the webview from the parent container first, and then destroy the webview:
rootLayout.removeView(webView); 
webView.destroy();

3.1. 2 about forward / backward page

//Can I go back
Webview.canGoBack() 
//Back page
Webview.goBack()

//Can we move forward                     
Webview.canGoForward()
//Forward page
Webview.goForward()

//Take the current index as the starting point to move forward or backward to the steps specified in the history
//If steps is negative, it is backward, and a positive number is forward
Webview.goBackOrForward(intsteps) 

Common usage: Back key controls the Back of web page

  • Problem: without any processing, click the "Back" key of the system when browsing the web page, and the whole Browser will call finish() to end itself
  • Objective: after clicking back, the web page will fall back rather than launch the browser
  • Solution: process and consume the Back event in the current Activity
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) { 
        mWebView.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3.1. 3 clear cached data

//Clear cache left by web page access
//Because the kernel cache is global, this method is not only for webview, but for the whole application
Webview.clearCache(true);

//Clear the history of current webview access
//Only the webview will access all records in the history except the current access record
Webview.clearHistory();

//This api only clears the automatically filled form data, and does not clear the data stored locally in WebView
Webview.clearFormData();

3.2 common categories

3.2.1 WebSettings class

  • Function: configure and manage WebView
  • Configuration steps & common methods:

Configuration step 1: add access to the network (AndroidManifest.xml)

This is the premise! This is the premise! This is the premise!

<uses-permission android:name="android.permission.INTERNET"/>

Configuration step 2: generate a WebView component (there are two ways)

//Method 1: generate directly in Activity
WebView webView = new WebView(this)

//Method 2: add webview control in the layout file of Activity:
WebView webview = (WebView) findViewById(R.id.webView1);

Configuration step 3: configure - use the WebSettings subclass (common method)

//Declare a subclass of WebSettings
WebSettings webSettings = webView.getSettings();

//If you want to interact with Javascript in the page you visit, the webview must be set to support Javascript
webSettings.setJavaScriptEnabled(true);  
// If JS is executing animation and other operations in the loaded html, it will cause a waste of resources (CPU and power)
// In onStop and onResume, set setjavascript enabled() to false and true respectively

//Support Plug-Ins
webSettings.setPluginsEnabled(true); 

//Set adaptive screen, both
webSettings.setUseWideViewPort(true); //Resize the picture to fit the webview 
webSettings.setLoadWithOverviewMode(true); // Zoom to screen size

//Zoom operation
webSettings.setSupportZoom(true); //Supports scaling. The default value is true. Is the premise of the following.
webSettings.setBuiltInZoomControls(true); //Sets the built-in zoom control. If false, the WebView is not scalable
webSettings.setDisplayZoomControls(false); //Hide native zoom controls

//Other details
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //Close the cache in webview 
webSettings.setAllowFileAccess(true); //Set access to files 
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //Support opening new windows through JS 
webSettings.setLoadsImagesAutomatically(true); //Support automatic loading of pictures
webSettings.setDefaultTextEncodingName("utf-8");//Set encoding format

Common usage: set WebView cache

  • When the html page is loaded, WebView will generate two folders, database and cache, under the directory of / data/data / package name
  • The requested URL record is saved in WebViewCache DB, and the content of the URL is saved in the WebViewCache folder
  • Enable caching:
    //Cache priority: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
        //The cache mode is as follows:
        //LOAD_CACHE_ONLY: do not use the network, only read the local cache data
        //LOAD_DEFAULT: (default) determines whether to fetch data from the network according to cache control.
        //LOAD_NO_CACHE: do not use cache, only get data from the network
        //LOAD_CACHE_ELSE_NETWORK, as long as it exists locally, uses the data in the cache regardless of whether it is expired or no cache.

    //Do not use cache: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
  • Combined use (offline loading)
if (NetStatusUtil.isConnected(getApplicationContext())) {
    webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//Decide whether to fetch data from the network according to cache control.
} else {
    webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//If there is no network, it is obtained locally, that is, it is loaded offline
}

webSettings.setDomStorageEnabled(true); // Enable DOM storage API function
webSettings.setDatabaseEnabled(true);   //Enable database storage API function
webSettings.setAppCacheEnabled(true);//Enable the Application Caches function

String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME;
webSettings.setAppCachePath(cacheDirPath); //Set Application Caches cache directory

Note: each Application only calls websettings once setAppCachePath(),WebSettings.setAppCacheMaxSize()

3.2.2 WebViewClient class

  • Role: handle various notification & request events
  • Common methods:

Common method 1: shouldOverrideUrlLoading()

  • Function: when opening a web page, it does not call the system browser, but is displayed in this WebView; All loads on the web page go through this method. We can do many operations with this function.
//Step 1 Define Webview components
Webview webview = (WebView) findViewById(R.id.webView1);

//Step 2 Select loading method
  //Mode 1 Load a web page:
  webView.loadUrl("http://www.google.com/");

  //Method 2: load the html page in apk package
  webView.loadUrl("file:///android_asset/test.html");

  //Method 3: load the local html page of the mobile phone
   webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");

//Step 3 Copy the shouldOverrideUrlLoading() method so that the system browser will not be called when opening the web page, but will be displayed in this WebView
    webView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          view.loadUrl(url);
      return true;
      }
  });

Common method 2: onPageStarted()

  • Function: when starting to load the page call, we can set a loading page to tell the user that the program is waiting for the network response.
   webView.setWebViewClient(new WebViewClient(){
     @Override
     public void  onPageStarted(WebView view, String url, Bitmap favicon) {
        //Set the operation at the beginning of loading
     }
 });

Common method 3: onPageFinished()

  • Function: called at the end of page loading. We can close the loading bar and switch program actions.
    webView.setWebViewClient(new WebViewClient(){
      @Override
      public void onPageFinished(WebView view, String url) {
         //Set the operation at the end of loading
      }
  });

Common method 4: onLoadResource()

  • Function: it will be called when loading page resources, and each resource (such as pictures) will be called once.
    webView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean onLoadResource(WebView view, String url) {
         //Set the operation of loading resources
      }
  });

Common method 5: onReceivedError ()

  • Function: called when the server loading the page has an error (such as 404).

When an error such as 404 is encountered when using the webview control in the app, if the error prompt page in the browser is also displayed, it will appear ugly. At this time, our app needs to load a local error prompt page, that is, how does webview load a local page

//Step 1: write an html file (error_handle.html) to display the prompt page to the user when an error occurs
//Step 2: place the html file in the assets folder of the code root directory

//Step 3: copy the onreceivederror method of WebViewClient
//This method returns the error code, which can be classified according to the error type
    webView.setWebViewClient(new WebViewClient(){
      @Override
      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
switch(errorCode)
                {
                case HttpStatus.SC_NOT_FOUND:
                    view.loadUrl("file:///android_assets/error_handle.html");
                    break;
                }
            }
        });

Common method 6: onReceivedSslError()

  • Role: Processing https requests

webView does not process https requests by default, and the page is blank. The following settings are required:

webView.setWebViewClient(new WebViewClient() {    
        @Override    
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {    
            handler.proceed();    //Indicates waiting for a certificate response
        // handler.cancel();      // Indicates that the connection is pending, which is the default mode
        // handler.handleMessage(null);    // Other treatment can be done
        }    
    });    

3.2.3 WebChromeClient class

  • Role: assist WebView in handling Javascript dialog boxes, website icons, website titles, etc.
  • Common usage:

Common method 1: onProgressChanged()

  • Function: get the loading progress of the web page and display it
webview.setWebChromeClient(new WebChromeClient(){

      @Override
      public void onProgressChanged(WebView view, int newProgress) {
          if (newProgress < 100) {
              String progress = newProgress + "%";
              progress.setText(progress);
            } else {
        }
    });

Common method 2: onReceivedTitle ()

  • Purpose: get the title in the Web page

Each page has a title, such as www.baidu.com Com the title of this page is "Baidu, you will know", so how to know and set the title of the page currently being loaded by webview?

webview.setWebChromeClient(new WebChromeClient(){

    @Override
    public void onReceivedTitle(WebView view, String title) {
       titleview.setText(title);
    }

Common method 3: onJsAlert()

  • Function: support javascript warning box

In general, Toast is used in Android. If you add \ n to the text, you can wrap the line

webview.setWebChromeClient(new WebChromeClient() {
            
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result)  {
    new AlertDialog.Builder(MainActivity.this)
            .setTitle("JsAlert")
            .setMessage(message)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    result.confirm();
                }
            })
            .setCancelable(false)
            .show();
    return true;
            }

Common method 4: onJsConfirm()

  • Function: support javascript confirmation box
webview.setWebChromeClient(new WebChromeClient() {
        
            @Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
    new AlertDialog.Builder(MainActivity.this)
            .setTitle("JsConfirm")
            .setMessage(message)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    result.confirm();
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    result.cancel();
                }
            })
            .setCancelable(false)
            .show();
// Return Boolean value: determines whether to confirm or cancel when clicking
// true means click OK; false indicates that cancel is clicked;
    return true;
}

            

Common method 5: onJsPrompt ()

  • Function: support javascript input box

Click OK to return the value in the input box, and click Cancel to return null.

webview.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
    final EditText et = new EditText(MainActivity.this);
    et.setText(defaultValue);
    new AlertDialog.Builder(MainActivity.this)
            .setTitle(message)
            .setView(et)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    result.confirm(et.getText().toString());
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    result.cancel();
                }
            })
            .setCancelable(false)
            .show();

    return true;
}
            

3.3 interaction between WebView and JavaScript

3.4 precautions: how to avoid WebView memory leakage?

3.4. 1. Instead of defining Webview in xml, it is created in Activity when necessary, 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);

3.4. 2 when the Activity destroys the WebView, first let the WebView load null content, then remove the WebView, then destroy the WebView, and finally leave it empty.

@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();
    }

4. Examples

  • Objective: to display "www.baidu.com", get its title, prompt the start & end of loading and get the loading progress
  • Specific implementation:

Step 1: add access to the network

This is the premise! This is the premise! This is the premise!

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>

Step 2: main layout activity\_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.carson_ho.webview_demo.MainActivity">


   <!-- Get the title of the site-->
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <!--Start loading prompt-->
    <TextView
        android:id="@+id/text_beginLoading"
        android:layout_below="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <!--Get load progress-->
    <TextView
        android:layout_below="@+id/text_beginLoading"
        android:id="@+id/text_Loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <!--End loading prompt-->
    <TextView
        android:layout_below="@+id/text_Loading"
        android:id="@+id/text_endLoading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>
    
    <!--Show web page area-->
    <WebView
        android:id="@+id/webView1"
        android:layout_below="@+id/text_endLoading"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginTop="10dp" />
</RelativeLayout>

Step 3: use the corresponding subclasses and their methods according to the functions to be implemented (the annotation is very clear) MainActivity.java

package com.example.carson_ho.webview_demo;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {
    WebView mWebview;
    WebSettings mWebSettings;
    TextView beginLoading,endLoading,loading,mtitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mWebview = (WebView) findViewById(R.id.webView1);
        beginLoading = (TextView) findViewById(R.id.text_beginLoading);
        endLoading = (TextView) findViewById(R.id.text_endLoading);
        loading = (TextView) findViewById(R.id.text_Loading);
        mtitle = (TextView) findViewById(R.id.title);

        mWebSettings = mWebview.getSettings();

        mWebview.loadUrl("http://www.baidu.com/");

        
        //Settings are displayed directly in the current Webview without opening the system browser
        mWebview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

        //Set WebChromeClient class
        mWebview.setWebChromeClient(new WebChromeClient() {


            //Get site title
            @Override
            public void onReceivedTitle(WebView view, String title) {
                System.out.println("The title is here");
                mtitle.setText(title);
            }


            //Get load progress
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress < 100) {
                    String progress = newProgress + "%";
                    loading.setText(progress);
                } else if (newProgress == 100) {
                    String progress = newProgress + "%";
                    loading.setText(progress);
                }
            }
        });


        //Set WebViewClient class
        mWebview.setWebViewClient(new WebViewClient() {
            //Set functions before loading
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                System.out.println("Loading started");
                beginLoading.setText("Loading started");

            }

            //Set end load function
            @Override
            public void onPageFinished(WebView view, String url) {
                endLoading.setText("Finished loading");

            }
        });
    }

    //Click to return to the previous page instead of exiting the browser
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && mWebview.canGoBack()) {
            mWebview.goBack();
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    //Destroy Webview
    @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();
    }
}

5. Summary

  • This article mainly gives a comprehensive introduction to Webview

    Related tutorials

    Android Foundation Series tutorials:

Android foundation course U-summary_ Beep beep beep_ bilibili

Android foundation course UI layout_ Beep beep beep_ bilibili

Android basic course UI control_ Beep beep beep_ bilibili

Android foundation course UI animation_ Beep beep beep_ bilibili

Android basic course - use of activity_ Beep beep beep_ bilibili

Android basic course - Fragment usage_ Beep beep beep_ bilibili

Android basic course - Principles of hot repair / hot update technology_ Beep beep beep_ bilibili

This article is transferred from https://juejin.cn/post/6844903479136223240 , in case of infringement, please contact to delete.

Topics: an-d-ro-id