Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”. First, the effect picture:

Introduction to mixed development

Native app: Java/Kotlin pure native written app;

Web app: Web written app;

Hybird App: Native + Web (via WebView) written app;

Of course, there are many third-party hybrid development frameworks and simple JS Bridges, but as the most basic webview, it is very necessary to master js/ Android intermodulation and other relevant knowledge.

Two Android – Js intermodulation

2.1 Prepare your own HTML files

Android and HTML js intermodulation, one is to have Android code, two must need HTML web pages. In the project, the web pages are placed on the server, which is convenient to change at any time. Users do not need to update their app again, which has achieved the purpose of hybrid development. For the convenience of the example, HTML files are stored locally.

First, create an Assets folder under the app directory in your Android project (if you don’t have one) :

Next, create your own HTML file under Assets as follows:

<html>
    <head>
        <meta http-equiv="Content-Type" charset="GB2312"/>
 
        <script type="text/javascript">
            function javacalljs(){
                 document.getElementById("showmsg").innerHTML = "JAVA calls JS functions without arguments";
            }
 
            function javacalljswith(arg){
                 document.getElementById("showmsg").innerHTML = (arg);
            }
 
        </script>
 
    </head>
 
    <body>
        <h3 align="center">The Web module</h3>
 
        <h3 id="showmsg" align="center">Call js to display the result</h3>
 
        <div style="text-align:center; vertical-align:middle;">
            <input  type="button" value="Js calling Java code" onclick="window.android.jsCallAndroid()"/>
        </div>
 
        <br>
 
        <br>
 
        <div style="text-align:center; vertical-align:middle;">
        <input  type="button" value="Js calls Java code and passes arguments" onclick="Window. The android. JsCallAndroidArgs (' Js to get the parameters')"/>
        </div>
 
    </body>
</html>
Copy the code

2.2 WebView control preparation Settings

After you get the WebView control in your activity, you need to set the following:

WebSettings webSettings = webview.getSettings();
// Interaction with js must be set
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/html.html");
webview.addJavascriptInterface(MainActivity.this."android");
Copy the code
  • WebSettings. SetJavaScriptEnabled (true) said that the WebView support call Js;
  • Webview. loadUrl(“file:///android_asset/html.html”) means to load html. HTML file under assets (local file loaded because there is no network address)
  • Webview. AddJavascriptInterface (MainActivity. This “android”) add Js to webview call interface, the first parameter as a class object, the second parameter for custom alias, Js through this nickname to call a Java method, I’m going to customize it for Android. HTML USES: < input type = “button” value = “Js invokes the Java code” &western nclick = “window. The android. JsCallAndroid ()” / >

2.3 Android Invokes Js code

In Android code (such as a button click event), loadUrl is called through the webView mediation to execute the Js code in the HTML code:

 tvJs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webview.loadUrl("javascript:javacalljs()"); }});Copy the code

The following is the code of the js function to be called by Android in HTML. The purpose of the function is to write the string “JAVA called JS function without arguments” to the h3 size title of showmsg.

function javacalljs(a){
                 document.getElementById("showmsg").innerHTML = "JAVA calls JS functions without arguments";
            }
Copy the code

Based on the above, if you want to pass parameters when Android calls Js functions, you only need to concatenate strings in loadUrl method, and concatenate parameters in string form.

webview.loadUrl("javascript:javacalljswith(" + "' Parameters passed by Android '" + ")");
Copy the code

2.4 Js calls Android methods and passes parameters

Click on the HTML button, through &western nclick = “window. The android. JsCallAndroid () event, through the android alias invokes the Java file jsCallAndroid () method. Javascript can directly call Java code to steal App information. For security purposes, Android4.4 and above must add @javascriptinterface to respond.

@JavascriptInterface
    public void jsCallAndroid(a){
        tvShowmsg.setText("Js calls Android methods");
    }

@JavascriptInterface
public void jsCallAndroidArgs(String args){
    tvShowmsg.setText(args);
}
Copy the code

The code for all activities is as follows:

package com.lucas.autils.autils;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;

  /** * Native WebView JS interworks with Android */
   public class JsJavaActivity extends Activity {

   private WebView webview;
   private TextView tvJs;
   private TextView tvJsArgs;
   private TextView tvShowmsg;

 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jsjava);
     
        setWebview();
        initView();
    }

    private void initView(a) {
        tvJs = (TextView) findViewById(R.id.tv_androidcalljs);
        tvJsArgs = (TextView) findViewById(R.id.tv_androidcalljsargs);
        tvShowmsg = (TextView) findViewById(R.id.tv_showmsg);
     
        tvJs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webview.loadUrl("javascript:javacalljs()"); }}); tvJsArgs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webview.loadUrl("javascript:javacalljswith(" + "' Parameters passed by Android '" + ")"); }}); }private void setWebview(a) {
        webview = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = webview.getSettings();
        webSettings.setBuiltInZoomControls(true);
        webSettings.setSupportZoom(true);
        // Interaction with js must be set
        webSettings.setJavaScriptEnabled(true);
        webview.loadUrl("file:///android_asset/html.html");
        webview.addJavascriptInterface(JsJavaActivity.this."android");
    }

    @JavascriptInterface
    public void jsCallAndroid(a){
        tvShowmsg.setText("Js calls Android methods");
    }
     
    @JavascriptInterface
    public void jsCallAndroidArgs(String args){ tvShowmsg.setText(args); }}Copy the code

Three commonly used methods and attention points

3.1 shouldOverrideUrlLoading in WebViewClient intercepts URLS

The setWebViewClient method in Android WebView needs a WebViewClient object, and the method in WebViewClient is shouldOverrideUrlLoading, which can intercept the URL address we need to jump to. And according to some of the operations we need to customize, parse the URL to do the corresponding thing.

3.2 onPageStarted in WebViewClient

OnPageStarted is called before the webView loads the url and is used to handle operations that need to be done before the url is loaded.

3.3 onPageFinished in WebViewClient

OnPageStarted is called after the webView has loaded the corresponding URL. It is often used to handle some operations that need to be done after loading the corresponding URL, such as filling the activity title at the top of the native page with the page title after loading.

EvaluateJavascript method for WebView

Execution of this method does not refresh the page, whereas execution of the method (loadUrl) does. This is available only after Android 4.4.

/ / intercept url
        webview.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url.indexOf("jump") > -1){
                    Toast.makeText(JsJavaActivity.this."The corresponding URL was intercepted.",Toast.LENGTH_LONG).show();
                    return true;
                }else if (url.startsWith("http")){
                    view.loadUrl(url);
                    return true;
                }
                return false;
            }
 
 
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                // when the page starts loading
            }
 
 
 
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // Load finished
 
                // Because execution of the method does not refresh the page, execution of the method (loadUrl) does.
                // Only available after Android 4.4
                webview.evaluateJavascript("javascript:changename()".new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        // This is the result returned by js
                        Log.v("Native",value); }}); }});Copy the code