Android: the most comprehensive Webview detailed explanation

content

Article directory


1 Introduction

WebView is a control based on the webkit engine that displays web pages.

Android's Webview uses different webkit version kernels in low and high versions, and uses Chrome directly after 4.4.

2. Function

  • Display and render web pages
  • Directly use html files (on the network or in local assets) for layout
  • Can be called interactively with JavaScript

The WebView control is powerful. In addition to the properties and settings of general View, it can also perform powerful processing on url requests, page loading, rendering, and page interaction.

3. Introduction

Generally speaking, Webview can be used alone or in conjunction 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 State of WebView

 

//Activate the WebView to be active, and can execute the response of the webpage normally
webView.onResume() ;

//When the page loses focus and is switched to the background invisible state, onPause needs to be executed
//Notify the kernel to suspend all actions through the onPause action, 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 the global webview of the whole application
//It will pause all webview's layout, parsing, javascripttimer. Reduce CPU power consumption.
webView.pauseTimers ()
//Restore pauseTimers state
webView.resumeTimers();

//Destroy Webview
//When the Activity is closed, if the music or video of the Webview is still playing. you must destroy the Webview
//But note: when the webview calls destroy, the webview is still bound to the Activity
//This is because the context object of the Activity is passed in when the custom webview is built
//So 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 web pages

/Can go back
Webview.canGoBack()
// go back to the page
Webview.goBack()

// can move forward                     
Webview.canGoForward()
//forward page
Webview.goForward()

/ / Use the current index as the starting point to move forward or backward to the steps specified in the history
//If steps is negative, it will go backward, if it is positive, it will go forward
Webview.goBackOrForward(intsteps)

 Common usage: Back key controls web page back

  • Problem: Without doing any processing, click the "Back" button of the system when browsing the web, the entire Browser will call finish() and end itself
  • Goal: When back is clicked, the page is rolled back instead of 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 cache data

    //Clear the cache left by web page visits
    // Since the kernel cache is global, this method is not only for the webview but for the entire application.
    Webview.clearCache(true);
    
    //Clear the history of the current webview access
    //Only webview accesses all records in the history except the current access record
    Webview.clearHistory();
    
    //This api only clears the autocomplete form data, and does not clear the data stored locally by the WebView
    Webview.clearFormData();

    3.2 Common classes

  • 3.2.1 WebSettings class

    • Role: Configure and manage WebView
    • Configuration steps & common methods:

    Configuration step 1: Add access network permissions (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 a webview control to the layout file of the Activity:
    WebView webview = (WebView) findViewById(R.id.webView1);
     Configuration Step 3: Make Configuration - Utilize WebSettings Subclass (Common Method)
    //declare the WebSettings subclass
    WebSettings webSettings = webView.getSettings();
    
    //If you want to interact with Javascript in the visited page, the webview must be set to support Javascript
    webSettings.setJavaScriptEnabled(true);  
    
    //support plugin
    webSettings.setPluginsEnabled(true);
    
    //Set the adaptive screen, use both
    webSettings.setUseWideViewPort(true); //Adjust the picture to fit the size of the webview
    webSettings.setLoadWithOverviewMode(true); // zoom to the size of the screen
    
    // zoom operation
    webSettings.setSupportZoom(true); //Support zoom, the default is true. It is the premise of the following.
    webSettings.setBuiltInZoomControls(true); //Set the built-in zoom controls. If false, the WebView is not zoomable
    webSettings.setDisplayZoomControls(false); //Hide native zoom controls
    
    //Other detailed operations
    webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //Close the cache in webview
    webSettings.setAllowFileAccess(true); //Set can access files
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //Support opening new windows through JS
    webSettings.setLoadsImagesAutomatically(true); //Support automatic loading of images
    webSettings.setDefaultTextEncodingName("utf-8");//Set the encoding format
    Common usage: set WebView cache
  • When loading an html page, WebView will generate two folders, database and cache, in the /data/data/package name directory.
  • The requested URL record is saved in WebViewCache.db, and the content of the URL is saved in the WebViewCache folder
  • Whether to enable caching:
    //Use the cache first:
        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: Don't use cache, just get data from network.
            //LOAD_CACHE_ELSE_NETWORK, as long as it is available locally, whether it expires or not, or no-cache, use the data in the cache.
    
        //don't use cache:
        WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
     
  • Combined use (offline loading)
    if (NetStatusUtil.isConnected(getApplicationContext())) {
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//According to cache-control to decide whether to fetch data from the network.
    } else {
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//If there is no network, get it locally, that is, offline loading
    }
    
    webSettings.setDomStorageEnabled(true); // Enable DOM storage API function
    webSettings.setDatabaseEnabled(true); //Enable database storage API function
    webSettings.setAppCacheEnabled(true);//Enable Application Caches function
    
    String cacheDirPath = getFilesDir (). GetAbsolutePath () + APP_CACAHE_DIRNAME;
    webSettings.setAppCachePath(cacheDirPath); //Set the Application Caches cache directory
     Note:  Each Application only calls WebSettings.setAppCachePath(), WebSettings.setAppCacheMaxSize() once

    3.2.2 WebViewClient class

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

    Common method 1: shouldOverrideUrlLoading()

    • Function: When opening a webpage, the system browser is not called, but displayed in this WebView; all loading on the webpage goes through this method, and we can do many operations with this function.

 

//Step 1. Define the Webview component
Webview webview = (WebView) findViewById(R.id.webView1);

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

  //Method 2: Load the html page in the 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. Override the shouldOverrideUrlLoading() method, so that the system browser is not called when the webpage is opened, but is 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 the loading page call, we can set a loading page to tell the user that the program is waiting for a network response.

 

webView.setWebViewClient(new WebViewClient(){
      @Override
      public void  onPageStarted(WebView view, String url, Bitmap favicon) {
         //Set the operation to start loading
      }
  });

 Common method 3: onPageFinished()

 

  • Role: Called at the end of page load. 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 of loading end
      }
  });

 Common method 4: onLoadResource()

 

  • Function: It will be called when the page resource is loaded, and it will be called once for each resource (such as an image) loaded.

 

webView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean onLoadResource(WebView view, String url) {
         //Set the operation to load the resource
      }
  });

Common method 5: onReceivedError()

  • Role: Called when there is an error (such as 404) on the server that loads the page.

When an error such as 404 is encountered when using the webview control in the app, it would be ugly if the error prompt page in the browser is also displayed, then our app needs to load a local error prompt at this time. The page, that is, how the webview loads a local page

 

//Step 1: Write an html file (error_handle.html) for the prompt page displayed to the user when an error occurs
//Step 2: Place the html file in the assets folder of the code root directory

//Step 3: Override the onRecievedError method of WebViewClient
//This method returns an error code, and different error classification processing can be performed according to the type of error
    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: handle https requests 

By default, webView does not process https requests, 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(); //represents waiting for certificate response
        // handler.cancel(); //Indicates suspending the connection, which is the default method
        // handler.handleMessage(null); //Other processing can be done
        }    
    });    

 

 

3.2.3 WebChromeClient class

  • Role: Assist WebView to handle Javascript dialogs, website icons, website titles, etc.
  • Common use:

Common method 1: onProgressChanged()

  • Role: 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()

  • Role: Get the title in the Web page 

The page of each web page has a title. For example, the title of the page www.baidu.com is "Baidu, you will know", so how to know the title of the page currently being loaded by the webview and set it?

 

webview.setWebChromeClient (new WebChromeClient () {

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

 

 

3.3 WebView与JS的交互

具体请看文章 Android WebView与JS的交互方式 最全面汇总

3.4 注意事项:如何避免WebView内存泄露?

3.4.1 不在xml中定义 Webview ,而是在需要的时候在Activity中创建,并且Context使用 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 在 Activity 销毁( WebView )的时候,先让 WebView 加载null内容,然后移除 WebView,再销毁 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();
    }

 

4. 实例

  • 目标:实现显示“www.baidu.com”、获取其标题、提示加载开始 & 结束和获取加载进度
  • 具体实现:

步骤1:添加访问网络权限

AndroidManifest.xml

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

 步骤2:主布局 

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">


   <!-- 获取网站的标题-->
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <!--开始加载提示-->
    <TextView
        android:id="@+id/text_beginLoading"
        android:layout_below="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <!--获取加载进度-->
    <TextView
        android:layout_below="@+id/text_beginLoading"
        android:id="@+id/text_Loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <!--结束加载提示-->
    <TextView
        android:layout_below="@+id/text_Loading"
        android:id="@+id/text_endLoading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <!--显示网页区域-->
    <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>

 步骤3:根据需要实现的功能从而使用相应的子类及其方法(注释很清楚了) 

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/");


        //设置不用系统浏览器打开,直接显示在当前Webview
        mWebview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

        //设置WebChromeClient类
        mWebview.setWebChromeClient(new WebChromeClient() {


            //获取网站标题
            @Override
            public void onReceivedTitle(WebView view, String title) {
                System.out.println("标题在这里");
                mtitle.setText(title);
            }


            //获取加载进度
            @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);
                }
            }
        });


        //设置WebViewClient类
        mWebview.setWebViewClient(new WebViewClient() {
            //设置加载前的函数
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                System.out.println("开始加载了");
                beginLoading.setText("开始加载了");

            }

            //设置结束加载函数
            @Override
            public void onPageFinished(WebView view, String url) {
                endLoading.setText("结束加载了");

            }
        });
    }

    //点击返回上一页面而不是退出浏览器
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && mWebview.canGoBack()) {
            mWebview.goBack();
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    //销毁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 ();
    }
}

 

 

Source code: Github-WebviewDemo by Carson_Ho

5. Summary

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326078425&siteId=291194637