Android 中 WebView 与原生通信

Overview

JsBridge

API Gradle-4.1.2

SDK支持

  • Js调用原生方法并支持异步回调和同步回调
  • 原生调用Js方法并支持异步回调
  • Js调用名称空间可自由配置,统一管理命名空间
  • 支持Js调用原生方法多次回调,如果不想多次回调可以删除回调方法
  • 支持部分Js框架中window并非顶级window

API介绍

  • callJsFunction(function: String)

    原生调用Js的方法,不支持传递参数和回调

    参数

    • function:调用Js的方法名称
  • callJsFunction(function: String, callback: JsCallback?)

    原生调用Js的方法,不支持传递参数但支持回调

    参数

    • function:调用Js的方法名称
    • callback:回调函数
  • callJsFunction(function: String, data: String?)

    原生调用Js的方法,支持传递参数,但不支持回调

    参数

    • function:调用Js的方法名称
    • data:字符串,传递给Js的参数
  • callJsFunction(function: String, data: String?, callback: JsCallback?)

    原生调用Js的方法,支持传递参数和回调

    参数

    • function:调用Js的方法名称
    • data:字符串,传递给Js的参数
    • callback:回调函数
  • jsCallName()

    Js调用原生的API命名空间,SDK统一了命名空间,默认为JsBridge,整个Js调用中只会使用这个命名,当然,如果是你不喜欢这个命名,或者需要根据项目更改为项目有关的命名,可以自定义WebView继承至BaseWebView重写该方法。

  • getWindow()

    Js中获取window的方法,建议不要随意修改。在特殊的Js框架中,获取系统的window需要window.window才能获取到,所以这时候可以自定义WebView继承至BaseWebView重写该方法。

如何使用

依赖引入

Step 1.先在 build.gradle(Project:XXX) 的 repositories 添加:

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

Step 2. 然后在 build.gradle(Module:XXX) 的 dependencies 添加:

dependencies {
       implementation 'com.github.ChinaLike:JsBridge:0.0.2'
}

新建Js调用原生方法的类,参考: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,"调用原生无参数无回调方法",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,"错误回调")
        },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,"错误回调")
        },3000)
    }

    @JavascriptInterface
    fun nativeSyncCallback():String{
        return "原生同步回调"
    }
}

新建MainActivity和xml文件,参考:MainActivityKotlinactivity_main

  • 在xml文件中引入JsBridgeWebView
">
<com.core.web.JsBridgeWebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

当然,如果没有特殊需要使用JsBridgeWebView就可以了,如果有定制WebView,则引入自己定制那个WebView就可以了,但是自定义的WebView需要继承BaseWebView

  • 在Activity中调用addJavascriptInterface添加
import com.core.web.JsBridgeWebView;

class MainActivityKotlin : AppCompatActivity() {

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

注意:webView的addJavascriptInterface方法可以多次调用,开发时可以根据业务功能进行解耦,addJavascriptInterface方法支持传递一个或两个参数,传递两个参数时第二个参数无效。

在Js中调用原生方法,参考:test.html

  • Js调用原生无参无回调方法

    • Kotlin代码
    @JavascriptInterface
    fun nativeNoArgAndNoCallback(){
        Toast.makeText(context,"调用原生无参数无回调方法",Toast.LENGTH_SHORT).show()
    }
    • Java代码
    @JavascriptInterface
    public void nativeNoArgAndNoCallback(){
        Toast.makeText(context,"调用原生无参数无回调方法",Toast.LENGTH_SHORT).show();
    }
    • Js代码
    JsBridge.nativeNoArgAndNoCallback();
  • Js调用原生无参有回调方法

    • Kotlin代码
    @JavascriptInterface
    fun nativeNoArgAndCallback(callback: Callback){
        callback.success()
    }
    • Java代码
    @JavascriptInterface
    public void nativeNoArgAndCallback(Callback callback){
        callback.success();
    }
    • Js代码
    JsBridge.nativeNoArgAndCallback(function(result){
        alert(JSON.stringify(result));
    });
  • Js调用原生有参无回调方法

    • Kotlin代码
    @JavascriptInterface
    fun nativeArgAndNoCallback(params:String){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
    }
    • Java代码
    @JavascriptInterface
    public void nativeArgAndNoCallback(String params){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show();
    }
    • Js代码
    JsBridge.nativeArgAndNoCallback("调用原生有参数无回调方法");
  • Js调用原生有参有回调方法

    • Kotlin代码
    @JavascriptInterface
    fun nativeArgAndCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success()
    }
    • Java代码
    @JavascriptInterface
    public void nativeArgAndCallback(String params,Callback callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show();
        callback.success();
    }
    • Js代码
    JsBridge.nativeArgAndCallback("调用原生有参数有回调方法",function(result){
        alert(JSON.stringify(result))
    });
  • Js调用原生有参有回调方法,且只能回调一次

    • Kotlin代码
    @JavascriptInterface
    fun nativeDeleteCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success(true)
        Handler().postDelayed(Runnable {
            callback.error(1,"错误回调")
        },3000)
    }
    • Java代码
    @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,"错误回调");
            }
        },3000);
    }
    • Js代码
    JsBridge.nativeDeleteCallback("调用原生方法后删除回调",function(result){
    			alert(JSON.stringify(result))
    		},function(error){
    			alert(JSON.stringify(result))
    		});
  • Js调用原生有参有回调方法,且能回调多次

    • Kotlin代码
    @JavascriptInterface
    fun nativeNoDeleteCallback(params:String,callback: Callback){
        Toast.makeText(context,params,Toast.LENGTH_SHORT).show()
        callback.success(false)
        Handler().postDelayed(Runnable {
            callback.error(1,"错误回调")
        },3000)
    }
    • Java代码
    @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,"错误回调");
            }
        },3000);
    }
    • Js代码
    JsBridge.nativeNoDeleteCallback("调用原生方法后不删除回调",function(result){
    			alert(JSON.stringify(result))
    		},function(error){
    			alert(JSON.stringify(error))
    		});
  • Js调用原生同步回调数据

    • Kotlin代码
    @JavascriptInterface
    fun nativeSyncCallback():String{
        return "原生同步回调"
    }
    • Java代码
    @JavascriptInterface
    public String nativeSyncCallback(){
        return "原生同步回调";
    }
    • Js代码
    var  result = JsBridge.nativeSyncCallback();
    alert(result)

注意:@JavascriptInterface注解的方法,只支持最多两个参数,不论顺序。无参数:代表Js不传递参数过来也不回调;一个参数:可以是传递过来的参数或回调;两个参数:一个为参数,一个是回调。

在原生中调用Js方法,参考:MainActivity

  • 原生调用JS无参数无回调

    • Js代码
    function jsNoArgAndNoCallback(){
        alert("原生调用JS无参数无回调");
    }
    • Java代码
    webView.callJsFunction("jsNoArgAndNoCallback");
    • Kotlin代码
    webView?.callJsFunction("jsNoArgAndNoCallback")
  • 原生调用Js无参数有回调

    • Js代码
    function jsNoArgAndCallback(callback){
            alert("原生调用JS无参数有回调");
            callback("我是JS回调数据");
    }
    • Java代码
    Toast.makeText(this, "" + callback, Toast.LENGTH_SHORT).show()); ">
    webView.callJsFunction("jsNoArgAndCallback", callback -> Toast.makeText(this, "" + callback, Toast.LENGTH_SHORT).show());
    • Kotlin代码
    webView?.callJsFunction("jsNoArgAndCallback", object : JsCallback {
            override fun onCallback(callback: Any) {
                Toast.makeText(this@MainActivityKotlin, "$callback", Toast.LENGTH_SHORT).show()
            }
        })
  • 原生调用Js有参数无回调

    • Js代码
    function jsArgAndNoCallback(params){
            alert(params);
    }
    • Java代码
    webView.callJsFunction("jsArgAndNoCallback", "原生传递过来的参数");
    • Kotlin代码
    webView?.callJsFunction("jsArgAndNoCallback","原生传递过来的参数")
  • 原生调用Js有参数有回调(可回调多次)

    • Js代码
    function jsArgAndCallback(params,callback){
            alert(params);
            callback("我是JS第一次回调数据");
            setTimeout(function() {
                    callback("我是JS第二次回调数据");
            }, 500);
    }
    • Java代码
    Toast.makeText(this, "" + callback, Toast.LENGTH_SHORT).show()); ">
    webView.callJsFunction("jsArgAndCallback", "原生传递过来的参数", callback -> Toast.makeText(this, "" + callback, Toast.LENGTH_SHORT).show());
    • Kotlin代码
    webView?.callJsFunction("jsArgAndCallback","原生传递过来的参数", object : JsCallback {
            override fun onCallback(callback: Any) {
                Toast.makeText(this@MainActivityKotlin, "$callback", Toast.LENGTH_SHORT).show()
            }
        })
  • 调用Js有参数有回调(只能回调一次)

    • Js代码
    function jsArgAndDeleteCallback(params,callback){
            alert(params);
            callback("我是JS第一次回调数据",true);
            setTimeout(function() {
                    callback("我是JS第二次回调数据");
            }, 500);
    }
    • Java代码
    Toast.makeText(this, "" + callback, Toast.LENGTH_SHORT).show()); ">
    webView.callJsFunction("jsArgAndDeleteCallback", "原生传递过来的参数", callback -> Toast.makeText(this, "" + callback, Toast.LENGTH_SHORT).show());
    • Kotlin代码
    webView?.callJsFunction("jsArgAndDeleteCallback","原生传递过来的参数", object : JsCallback {
            override fun onCallback(callback: Any) {
                Toast.makeText(this@MainActivityKotlin, "$callback", Toast.LENGTH_SHORT).show()
            }
        })

注意:原生调用Js代码,Js的方法最多支持两个参数,无参数:代表原生不传递参数过来也不用回调给原生; 一个参数:可以是参数也可以是回调;两个参数:有序,第一个为参数,第二个为回调,代表原生传递过来参数,且需要回调给原生

You might also like...
Run Node.js on Android by rewrite Node.js in Java

node-android Run Node.js on Android by rewrite Node.js in Java with the compatible API. third-party: libuvpp, libuv-java JNI code by Oracle. Build Clo

dns library for android

Qiniu Happy DNS for Android 安装 直接安装 通过maven 使用方法 DnsManager 可以创建一次,一直使用。 IResolver[] resolvers = new IResolver[3]; resolvers[0] = AndroidDnsSe

HTTP Server for Android Instrumentation tests

RESTMock REST API mocking made easy. RESTMock is a library working on top of Square's okhttp/MockWebServer. It allows you to specify Hamcrest matchers

🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀
🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀

Fast Android Networking Library About Fast Android Networking Library Fast Android Networking Library is a powerful library for doing any type of netw

Support for Spring's RestTemplate within native Android applications

Spring for Android Spring for Android is a library that is designed to provide components of the Spring Framework family of projects for use in native

The easiest HTTP networking library for Kotlin/Android

Fuel The easiest HTTP networking library for Kotlin/Android. You are looking at the documentation for 2.x.y.. If you are looking for the documentation

Asynchronous socket, http(s) (client+server) and websocket library for android. Based on nio, not threads.

AndroidAsync AndroidAsync is a low level network protocol library. If you are looking for an easy to use, higher level, Android aware, http request li

LiteHttp is a simple, intelligent and flexible HTTP framework for Android. With LiteHttp you can make HTTP request with only one line of code! It could convert a java model to the parameter and rander the response JSON as a java model intelligently.

Android network framework: LiteHttp Tags : litehttp2.x-tutorials Website : http://litesuits.com QQgroup : 42960650 , 47357508 Android网络通信为啥子选 lite-htt

The best file downloader library for Android
The best file downloader library for Android

Overview Fetch is a simple, powerful, customizable file download manager library for Android. Features Simple and easy to use API. Continuous download

Releases(0.0.3)
Owner
null
:satellite: [Android Library] Simplified async networking in android

Android library that simplifies networking in android via an async http client. Also featured in [Awesome Android Newsletter #Issue 15 ] Built with ❤︎

Nishant Srivastava 36 May 14, 2022
Android network client based on Cronet. This library let you easily use QUIC protocol in your Android projects

Android network client based on Cronet. This library let you easily use QUIC protocol in your Android projects

VK.com 104 Dec 12, 2022
Android Easy Http - Simplest android http request library.

Android Easy Http Library 繁體中文文檔 About Android Easy Http Library Made on OkHttp. Easy to do http request, just make request and listen for the respons

null 13 Sep 30, 2022
Android Asynchronous Networking and Image Loading

Android Asynchronous Networking and Image Loading Download Maven Git Features Kotlin coroutine/suspend support Asynchronously download: Images into Im

Koushik Dutta 6.3k Dec 27, 2022
Square’s meticulous HTTP client for the JVM, Android, and GraalVM.

OkHttp See the project website for documentation and APIs. HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP

Square 43.4k Jan 5, 2023
A type-safe HTTP client for Android and the JVM

Retrofit A type-safe HTTP client for Android and Java. For more information please see the website. Download Download the latest JAR or grab from Mave

Square 41k Jan 5, 2023
Android client for ProjectRTC - a WebRTC demo

AndroidRTC WebRTC Live Streaming An Android client for ProjectRTC. It is designed to demonstrate WebRTC video calls between androids and/or desktop br

Chabardes 1.5k Jan 6, 2023
IceNet - Fast, Simple and Easy Networking for Android

IceNet FAST, SIMPLE, EASY This library is an Android networking wrapper consisting of a combination of Volley, OkHttp and Gson. For more information s

Anton Nurdin Tuhadiansyah 61 Jun 24, 2022
Easy, asynchronous, annotation-based SOAP for Android

IceSoap IceSoap provides quick, easy, asynchronous access to SOAP web services from Android devices. It allows for SOAP responses to be bound to Java

Alex Gilleran 75 Nov 29, 2022