An webview control and an javascript interaction instance in android

  • 2020-06-01 11:00:04
  • OfStack

When we want to achieve rich graphics mixing effect, we will use webview, which is a powerful 10 function control, to see the official explanation:

A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit rendering engine to display web pages and includes methods to navigate forward and backward through a history, zoom in and out, perform text searches and more.

An View that displays web content. This class is the basis for you to implement a browser of your own, or just display web content in activity. It is based on the WebKit kernel to display web pages, and includes methods to turn pages back and forth, zoom in and out, and text search.

From the above you should know the basic function, which is to display the web page. In this article we focus on the interaction between webview and Javascript. If your js base is better than your java base then this is a good way to do some complex processing.

The interaction between WebView and js consists of two aspects. 1 is to invoke android java code through js in html; 2. 2 is to call js in the android java code.

1. html calls java code through js

The code that calls java in js actually remembers one point. webview sets up an interface to interact with js (note that this only means "1", not "java"). The interface is actually a "1" class and gives the interface a single name. The process is as follows:


mWebView.addJavascriptInterface(new DemoJavaScriptInterface(),"demo");

new DemoJavaScriptInterface is the interface, and demo is the alias for the interface.
The code above is then executed in html's js to invoke any method in the newDemoJavaScriptInterface class through an alias (in this case, "demo").

If we want one of html's button to click and then call the function in java, we can do this:


<input type="button"  value="click me"  onclick="window.demo.clickOnAndroid()"/>

However, for security reasons, in Android4.2 (if the android:targetSdkVersion value is 17+)JS can only access the Java function with the @JavascriptInterface annotation. So if your development version is high, you need to annotate the @JavascriptInterface annotation before the function is called.

Here's a code example from Google:
WebViewDemo.java


package com.google.android.webviewdemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
/**
 * Demonstrates how to embed a WebView in your activity. Also demonstrates how
 * to have javascript in the WebView call into the activity, and how the activity
 * can invoke javascript.
 * <p>
 * In this example, clicking on the android in the WebView will result in a call into
 * the activities code in {@link DemoJavaScriptInterface#clickOnAndroid()}. This code
 * will turn around and invoke javascript using the {@link WebView#loadUrl(String)}
 * method.
 * <p>
 * Obviously all of this could have been accomplished without calling into the activity
 * and then back into javascript, but this code is intended to show how to set up the
 * code paths for this sort of communication.
 *
 */
public class WebViewDemo extends Activity {
    private static final String LOG_TAG = "WebViewDemo";
    private WebView mWebView;
    private Handler mHandler = new Handler();
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
        mWebView = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setSavePassword(false);
        webSettings.setSaveFormData(false);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setSupportZoom(false);
        mWebView.setWebChromeClient(new MyWebChromeClient());
        mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
        mWebView.loadUrl("file:///android_asset/demo.html");
    }
    final class DemoJavaScriptInterface {
        DemoJavaScriptInterface() {
        }
        /**
         * This is not called on the UI thread. Post a runnable to invoke
         * loadUrl on the UI thread.
         */
        public void clickOnAndroid() {
            mHandler.post(new Runnable() {
                public void run() {
                    mWebView.loadUrl("javascript:wave()");
                }
            });
        }
    }
    /**
     * Provides a hook for calling "alert" from javascript. Useful for
     * debugging your javascript.
     */
    final class MyWebChromeClient extends WebChromeClient {
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            Log.d(LOG_TAG, message);
            result.confirm();
            return true;
        }
    }
}

demo.html


<html>
    <script language="javascript">
        /* This function is invoked by the activity */
        function wave() {
            alert("1");
            document.getElementById("droid").src="android_waving.png";
            alert("2");
        }
    </script>
    <body>
        <!-- Calls into the javascript interface for the activity -->
        <a onClick="window.demo.clickOnAndroid()"><div style="width:80px;
            margin:0px auto;
            padding:10px;
            text-align:center;
            border:2px solid #202020;" >
                <img id="droid" src="android_normal.png"/><br>
                Click me!
        </div></a>
    </body>
</html>

main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >                                            
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/intro"
        android:padding="4dip"
        android:textSize="16sp"
        />
    <WebView
        android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        />
</LinearLayout>

2. android calls js

The code above shows how to call js from java, as well as java from js
Call form:

mWebView.loadUrl("javascript:wave()");

wave () is one of the methods in js, but of course you can change this method to something else, which is android calling another method.

Explanation of demo:

Now you must understand the interaction between android and js. It's time to analyze some demo, and you should know better from the above. The specific interaction process is as follows:

Click the picture, then directly call the method clickOnAndroid() on js;
The clickOnAndroid() method calls the js method (using threads).
The js called by directly controls html.

Personal summary: the use of webView this way in some cases UI layout can be converted to the corresponding html code written, and html layout style such as DW such a powerful tool, and a lot of source code, a lot of code pieces on the Internet. With the UI and the visual effects, there's no point in reinventing the wheel.


Related articles: