In the Android native development, should be 80% will encounter native and Js mixed call, there are many examples on the Internet, can achieve the requirements, but the basic surface implementation, of course, there are some also write very good, but I do not know why did not update, and then the project is missing files. In fact, we call each other in WebView and native, nothing more than the following questions:

  • Native call Js, how Js asynchronous callback to the native, the same call callback many times, a callback, two callback, three…… ?
  • Js call native, native how asynchronous callback to Js, the same call callback many times, a callback, two callback, three…… ? Not through the WebViewloadUrlWhat about executing JS for callbacks?
  • What do I want to do when I’m writing Js?
  JsBridge.nativeDeleteCallback("Delete callback after calling native method".function(result){
	alert(JSON.stringify(result))
    },function(error){
	alert(JSON.stringify(result))
  });
Copy the code

In view of the above problems, this article also solved the problem of writing accordingly, refer to Demo, you can also download Demo at a glance after running.

The SDK support

  • Js calls native methods and supports both asynchronous and synchronous callbacks
  • Calls Js methods natively and supports asynchronous callbacks
  • Js call namespace can be freely configured, unified management of the namespace
  • Support Js to call native method callback multiple times, if you do not want to callback multiple times can delete the callback method
  • Support for some Js frameworks where Windows are not top-level Windows

The API is introduced

  • callJsFunction(function: String)

    Calls Js methods natively, with no support for passing arguments and callbacks

    parameter

    • Function: the name of the method to call Js
  • callJsFunction(function: String, callback: JsCallback?)

    A native call to a Js method that does not support passing arguments but supports callbacks

    parameter

    • Function: the name of the method to call Js
    • Callback: callback function
  • callJsFunction(function: String, data: String?)

    Native calls to Js methods that support passing arguments, but do not support callbacks

    parameter

    • Function: the name of the method to call Js
    • Data: a string, passed to Js as an argument
  • callJsFunction(function: String, data: String? , callback: JsCallback?)

    Native calls to Js methods with support for passing arguments and callbacks

    parameter

    • Function: the name of the method to call Js
    • Data: a string, passed to Js as an argument
    • Callback: callback function
  • jsCallName()

    If you don’t like the name, or need to change it to a project-specific name, you can override this method by using a custom WebView inherited from BaseWebView.

  • getWindow()

    Js to obtain the window. Do not change it at will. In a special Js framework, window.window is required to obtain the system window, so you can override this method by inherits BaseWebView from WebView.

How to use

Depend on the introduction of

Step 1 add Repositories for Build. Gradle (Project:XXX)

allprojects {
	repositories {
		...
		maven { url "https://jitpack.io" }
	}
}
Copy the code

Step 2. Add dependencies to build.gradle(Module:XXX)

Dependencies {implementation 'com. Making. ChinaLike: JsBridge: hundreds'}Copy the code

Create a new class that calls native methods.JsBridgeToast

package com.like.jsbridge

import android.content.Context
import android.os.Handler
import android.util.Log
import android.webkit.JavascriptInterface
import android.widget.Toast
import com.core.web.Callback
import com.core.web.CallbackBean

class JsBridgeToast(private val context: Context)  {

    @JavascriptInterface
    fun nativeNoArgAndNoCallback(){
        Toast.makeText(context,"Call native no-argument no-callback method",Toast.LENGTH_SHORT).show()
    }

    @JavascriptInterface
    fun nativeNoArgAndCallback(callback: Callback){
        callback.success()
    }

    @JavascriptInterface
    fun nativeArgAndNoCallback(params:String){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
    }

    @JavascriptInterface
    fun nativeArgAndCallback(params:String.callback: Callback):Boolean{
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success()

        return false
    }

    @JavascriptInterface
    fun nativeDeleteCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success(isDelete = true)
        Handler().postDelayed(Runnable {
            callback.error(1."Error callback")},3000)
    }

    @JavascriptInterface
    fun nativeNoDeleteCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success(isDelete = false)
        Handler().postDelayed(Runnable {
            callback.error(1."Error callback")},3000)
    }

    @JavascriptInterface
    fun nativeSyncCallback():String{
        return "Native synchronization callback"}}Copy the code

Create a new MainActivity and XML file.MainActivityKotlinandactivity_main

  • Introduce JsBridgeWebView in an XML file
<com.core.web.JsBridgeWebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
Copy the code

Of course, if you have no special need to use JsBridgeWebView, if you have a custom WebView, you can introduce your own custom WebView, but the custom WebView needs to inherit from BaseWebView

  • Called in an ActivityaddJavascriptInterfaceadd
import com.core.web.JsBridgeWebView;

class MainActivityKotlin : AppCompatActivity(a){

    private var webView: JsBridgeWebView? = null
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) webView = findViewById(R.id.webView) webView? .addJavascriptInterface(JsBridgeToast(this)) webView? .loadUrl("file:///android_asset/test.html")}Copy the code

Note: The addJavascriptInterface method of webView can be called multiple times and can be decoupled by business function at development time. The addJavascriptInterface method supports passing one or two parameters. If passing two parameters, the second parameter is invalid.

To call native methods in Js, refer to:test.html

  • Js calls native methods with no arguments and no callbacks

    • Kotlin code
    @JavascriptInterface
    fun nativeNoArgAndNoCallback(){
        Toast.makeText(context,"Call native no-argument no-callback method",Toast.LENGTH_SHORT).show()
    }
    Copy the code
    • Java code
    @JavascriptInterface
    public void nativeNoArgAndNoCallback(){
        Toast.makeText(context,"Call native no-argument no-callback method",Toast.LENGTH_SHORT).show();
    }
    Copy the code
    • Js code
    JsBridge.nativeNoArgAndNoCallback();
    Copy the code
  • Js calls native callback methods with no parameters

    • Kotlin code
    @JavascriptInterface
    fun nativeNoArgAndCallback(callback: Callback){
        callback.success()
    }
    Copy the code
    • Java code
    @JavascriptInterface
    public void nativeNoArgAndCallback(Callback callback){
        callback.success();
    }
    Copy the code
    • Js code
    JsBridge.nativeNoArgAndCallback(function(result){
        alert(JSON.stringify(result));
    });
    Copy the code
  • Js calls native methods with no callback

    • Kotlin code
    @JavascriptInterface
    fun nativeArgAndNoCallback(params:String){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
    }
    Copy the code
    • Java code
    @JavascriptInterface
    public void nativeArgAndNoCallback(String params){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show();
    }
    Copy the code
    • Js code
    JsBridge.nativeArgAndNoCallback("Call native methods with arguments and no callback");
    Copy the code
  • Js calls native methods with parameters and callbacks

    • Kotlin code
    @JavascriptInterface
    fun nativeArgAndCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success()
    }
    Copy the code
    • Java code
    @JavascriptInterface
    public void nativeArgAndCallback(String params,Callback callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show();
        callback.success();
    }
    Copy the code
    • Js code
    JsBridge.nativeArgAndCallback("Call native methods with arguments and callbacks".function(result){
        alert(JSON.stringify(result))
    });
    Copy the code
  • Js calls native methods with parameters and callback methods, and can only callback once

    • Kotlin code
    @JavascriptInterface
    fun nativeDeleteCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success(true)
        Handler().postDelayed(Runnable {
            callback.error(1."Error callback")},3000)}Copy the code
    • Java code
    @JavascriptInterface
    public void nativeDeleteCallback(String params,Callback callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show();
        callback.success(true);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                callback.error(1."Error callback"); }},3000);
    }
    Copy the code
    • Js code
    JsBridge.nativeDeleteCallback("Delete callback after calling native method".function(result){
    			alert(JSON.stringify(result))
    		},function(error){
    			alert(JSON.stringify(result))
    		});
    Copy the code
  • Js call native parameters have callback methods, and can callback many times

    • Kotlin code
    @JavascriptInterface
    fun nativeNoDeleteCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success(false)
        Handler().postDelayed(Runnable {
            callback.error(1."Error callback")},3000)}Copy the code
    • Java code
    @JavascriptInterface
    public void nativeNoDeleteCallback(String params,Callback callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show();
        callback.success(false);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                callback.error(1."Error callback"); }},3000);
    }
    Copy the code
    • Js code
    JsBridge.nativeNoDeleteCallback("Callback not deleted after calling native method".function(result){
    			alert(JSON.stringify(result))
    		},function(error){
    			alert(JSON.stringify(error))
    		});
    Copy the code
  • Js calls native synchronization callback data

    • Kotlin code
    @JavascriptInterface
    fun nativeSyncCallback():String{
        return "Native synchronization callback"
    }
    Copy the code
    • Java code
    @JavascriptInterface
    public String nativeSyncCallback(){
        return "Native synchronization callback";
    }
    Copy the code
    • Js code
    var  result = JsBridge.nativeSyncCallback();
    alert(result)
    Copy the code

Note: Methods annotated by @javascriptInterface only support a maximum of two parameters, regardless of order. No parameter: indicates that Js does not pass parameters and does not call back; An argument: it can be a passed argument or a callback. Two parameters: a parameter and a callback.

To call Js methods from native, refer to:MainActivity

  • Native JS calls with no arguments and no callbacks

    • Js code
    function jsNoArgAndNoCallback(){
        alert("Native JS call with no arguments and no callbacks");
    }
    Copy the code
    • Java code
    webView.callJsFunction("jsNoArgAndNoCallback");
    Copy the code
    • Kotlin code
    webView? .callJsFunction("jsNoArgAndNoCallback")
    Copy the code
  • Native Js calls have callbacks without arguments

    • Js code
    function jsNoArgAndCallback(callback){
            alert("Native JS call with no arguments and callback");
            callback("I am JS callback data");
    }
    Copy the code
    • Java code
    webView.callJsFunction("jsNoArgAndCallback", callback -> Toast.makeText(this."" + callback, Toast.LENGTH_SHORT).show());
    Copy the code
    • Kotlin code
    webView? .callJsFunction("jsNoArgAndCallback".object : JsCallback {
            override fun onCallback(callback: Any) {
                Toast.makeText(this@MainActivityKotlin, "$callback", Toast.LENGTH_SHORT).show()
            }
        })
    Copy the code
  • Native calls to Js have arguments and no callbacks

    • Js code
    function jsArgAndNoCallback(params){
            alert(params);
    }
    Copy the code
    • Java code
    webView.callJsFunction("jsArgAndNoCallback"."Primitively passed parameters");
    Copy the code
    • Kotlin code
    webView? .callJsFunction("jsArgAndNoCallback"."Primitively passed parameters")
    Copy the code
  • Native Js calls with arguments and callbacks (callback multiple times)

    • Js code
    function jsArgAndCallback(params,callback){
            alert(params);
            callback("I am JS callback data for the first time.");
            setTimeout(function() {
                    callback("I am JS second callback data");
            }, 500);
    }
    Copy the code
    • Java code
    webView.callJsFunction("jsArgAndCallback"."Primitively passed parameters", callback -> Toast.makeText(this."" + callback, Toast.LENGTH_SHORT).show());
    Copy the code
    • Kotlin code
    webView? .callJsFunction("jsArgAndCallback"."Primitively passed parameters".object : JsCallback {
            override fun onCallback(callback: Any) {
                Toast.makeText(this@MainActivityKotlin, "$callback", Toast.LENGTH_SHORT).show()
            }
        })
    Copy the code
  • Calls to Js with arguments and callbacks (only one callback)

    • Js code
    function jsArgAndDeleteCallback(params,callback){
            alert(params);
            callback("I am JS callback data for the first time.".true);
            setTimeout(function() {
                    callback("I am JS second callback data");
            }, 500);
    }
    Copy the code
    • Java code
    webView.callJsFunction("jsArgAndDeleteCallback"."Primitively passed parameters", callback -> Toast.makeText(this."" + callback, Toast.LENGTH_SHORT).show());
    Copy the code
    • Kotlin code
    webView? .callJsFunction("jsArgAndDeleteCallback"."Primitively passed parameters".object : JsCallback {
            override fun onCallback(callback: Any) {
                Toast.makeText(this@MainActivityKotlin, "$callback", Toast.LENGTH_SHORT).show()
            }
        })
    Copy the code

Note: native calls to Js code, Js methods support a maximum of two parameters, no parameters: the native does not pass parameters to the native and do not need to call back to the native; A parameter: can be a parameter or a callback; Two parameters: order, the first is a parameter, the second is a callback, which represents the parameter passed by the native and needs to be called back to the native

If there are questions welcome to leave a message source address