jsBridge

apk 和 H5 混合

1.汇总

jsbridge 是 java 和 js 之间的一个桥梁

最主要的就是 两端的通信

安全

效率

覆盖率

解决的问题

1.漏洞问题

2.代码繁琐问题

3.android 接收 js 的回调只支持 android4.4 以上的版本

2.本质问题

1. java 调用 js

2. js 调用 java

原生调用方式

java 调用 js

webView.loadUrl("javascript:alertMsg(" + "'Android传过来的参数'" + ")")

本质:是一个拼接 js 字符串的过程.

但是 loadUrl 不能直接获取返回值,要获取返回值可以通过webview.evaluateJavaScript方法,但是此方法只有 android4.4 及以上才可以使用.

webView.evaluateJavascript("javascript:alertMsg(" + "'Android传过来的参数'" + ")") { s ->
    button.text = s
}

js 调用 java

有三种方式 : 对象映射,URL 拦截,js 方法拦截

1.对象映射

就可以在 js 中直接调用 javaObject对象,从而实现此功能.但是此方法在 android4.2 下有安全漏洞,可以利用反射机制调用 android api getRuntime 执行 shell 命令攻击(遍历sdcard、发送短信、安装木马APK等)

android

public  class  JsInteration  {
    @JavascriptInterface
    public  String  back() {
        return "hello world";
    }
}

webView.addJavascriptInterface(new JsInteration(),"android");

js

window.android.back();

这是一次交互,如果是N次呢?

攻击代码

2.url 拦截

通过iframe.src、window.open、documention.location或者href,这四种方法都可以在html页面中打开一个连接,从而会触发Java中的WebViewClient.shouldOverrideUrlLoading方法.

例如:js 中执行

document.location = 'http://www.baidu.com/{"data":{"username":"tom"}}'

webView.webViewClient = object : WebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
            Log.e("cml",url)
            return super.shouldOverrideUrlLoading(view, url)
        }
    }    

3.js 方法拦截

在JS中调用alert、console、prompt、confirm等方法就会触发WebChromeClient的onJsAlert、onConsoleMessage、onJsPrompt、onJsConfirm方法的回调.

 


JSbridge

Jsbridge github address

它主要解决的问题就两个

1.回调问题

在java端和js端定义一个数据结构: Message={callbackId:xxx, handleName:xxx,responseData:xxx,responseId:xxx}将回调函数保存在callbackId中,当JS或者Java处理完数据回调的时候再将保存在callbackId的回调函数存放在responseId,相应的回调的数据存放在responseData中,这样就能响应JS或者Java调用后的回调消息

2.js 调用 android 使用哪种方式

Js调用Java的方法虽然有三种,

addJavaScriptInterface存在安全性问题一般不建议使用,

JS中的alert、console方法都会在Html页面比较常用,confirm和prompt虽然不常用但是某些手机系统版本上会有对话框弹出,不通用.

比较好的选择是url拦截,可以通过iframe.src触发shouldOverrideUrlLoading.

流程图

从 java 看

从 js 看

在H5页面加载完毕注入一个本地的js文件;

Java代码中注册BridgeHandler,用来处理JS发送过来的消息;

在本地注入的js文件中定义_handleMessageFromNative,用来接收java传递过来的消息;

因为客户端注入js是异步的,所以需要在js文件中注册Event监听器,成功后通知H5。