JSBridge-Android

樊熠彤
2023-12-01

备注:近期在处理js和安卓原生webView交互方式时发现,前端使用的是WebViewJavascriptBridge的一种方式,可以前后端双向交互,之前没有接触过,查找资料发现IOS使用的是IOS WebViewJavascriptBridge,网上很少有安卓这方面的资料,通过在GitHub上查找,发现有开源的安卓的Bridge方式和IOS的使用方式一致。最终使用的是smallbuer优化后的原作者lzyzsdJsBridge,在此记录下。

简介

JSBridge-Android原理:

不再使用URL SHEME拦截方式,直接采用webview的addJavaScriptInterface,此方法根据Android源码跟踪,是目前采用webview方案js与原生交互效率最高的一种系统实现; 对于API小于17的使用者,1.0.3版本将支持版本降低到14,满足一些朋友的需要,为了安全主要实现方式利用onJsPrompt方法让H5可以和原生进行交互,并且移除了低版本的三个危险漏洞;

接入方式

dependencies {
      implementation 'com.smallbuer:jsbridge:1.0.3'
}

 xml中使用时导入具体的包:

<com.smallbuer.jsbridge.core.BridgeWebView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/bridgeWebview"
    android:layout_weight="1"
    />

 

 H5调用

H5中可以自己封装调用名称,适合Vue.js或者存js调用;

window.WebViewJavascriptBridge.callHandler(
                'toast'                     //桥注册的名称ID
                , {'msg': '中文测试'}        //传递给原生的参数
                , function(responseData) {  //异步回调接口
                    console.log('native return->'+responseData);
                }
            );

 X5WebView

外部扩展其他webview,比如X5内核,uc内核等,源码请参考demo中X5WebView实现

备注:这里X5采用的是 com.tencent.smtt.sdk.WebView

(1)新建X5WebView继承X5包内的webview并实现IWebView接口
(2)在X5WebView中新建BridgeTiny并传入X5WebView对应,BridgeTiny作为一个webview的管理类;

// 这里使用时发现部分方法需要在加载前调用,修改为WebViewClient 中的 onPageStarted时加载

// 调试时发现部分手机onPageStarted中无法加载js脚本配置,因此onPageStarted|onLoadResource|shouldOverrideUrlLoading|onPageFinished中都做了添加
(3)在webview执行onPageFinished时,加载js脚本内容用于执行对象的注册;
(4)在webview执行destroy时清空使用内存;

注册JSBridge处理方法

备注:在创建BridgeHandler时没有采用作者的方法去创建每一个handler的class,而是创建了JSBridgeHandler类方便管理,通过具体的方法获取需要注册的BridgeHandler对象。当然这里只适合比较简单的功能,如果遇到需要同webView,activity进行交互的,需要在具体activity页面进行创建。

注意:bridgeTiny = new BridgeTiny(this); 不能放到 X5WebView 的构造方法中初始化

因为BridgeTiny在创建时已经注册了所有的BridgeHandler,如果存在复杂的需求时,单独添加是无效的,所以应该把方法暴露出来,提供给外部主动调用进行注册。
mMessageHandlers.putAll(Bridge.INSTANCE.getMessageHandlers());
public void initBridgeTiny(){
   bridgeTiny = new BridgeTiny(this);
}
 
/**
 * 创建 JSBridge 对外提供的 BridgeHandler功能类
 */
public class JSBridgeHandler {

    public static final String TAG = "JSBridgeHandler";

    public static final String CHAT_SELECT_FILES = "chatSelectFiles";
    public static final String CLOSE = "close";
    public static final String SET_TITLE = "setTitle";
    public static final String GET_SYSTEM_INFO = "getSystemInfo";
    public static final String GET_ADDRESS_INFO = "getAddressInfo";

    public static BridgeHandler chatSelectFiles(){
        return new BridgeHandler(){
            @Override
            public void handler(Context context, String file_url, CallBackFunction function) {
                // ...function.onCallBack(result.toJSONString());
            }
        };
    }
// ...
}
    private void initJSBridgeHandler() {
        Map<String, BridgeHandler> handlerMap = new HashMap<>();
        handlerMap.put(JSBridgeHandler.GET_SYSTEM_INFO,JSBridgeHandler.getSystemInfo());
        handlerMap.put(JSBridgeHandler.SET_TITLE,JSBridgeHandler.setTitle());
        handlerMap.put(JSBridgeHandler.GET_ADDRESS_INFO,JSBridgeHandler.getAddressInfo());
        handlerMap.put(JSBridgeHandler.CLOSE,JSBridgeHandler.close());
       handlerMap.put(JSBridgeHandler.CHAT_SELECT_FILES,JSBridgeHandler.chatSelectFiles());
        Bridge.INSTANCE.registerHandler(handlerMap);
    }

 

 类似资料: