跨端之桥方法原理及实现
title: js-bridge date: 2020-08-28 20:25:06 categories: js
本文探讨 js 与 app 原生的交互
场景
移动端页面需要和 app 进行一些交互,比如获取在 app 中的用户信息,分享后回调需要 app 来通知 h5 完成页面渲染,js 中调用 app 方法等
webView
webview 是android 加载网页的一个控件,可以通过 webview 加载网络/本地的html,或者运行网络/本地的js
native 调用 js方法
前提在 webview 中开启对 js 支持,初始化 webview 中添加 webSetting.setJavaScriptEnabled(true)
loadUrl
:webview 中方法,传入参数中添加以javascript:
为前缀,加上对应的 js 方法(即 function),在onPageFinished
(载入页面完成,但在不同内核里调用的实际好像不一样)后才会运行evaluageJavaScript
:webview 中方法,传入参数同 loadUrl 相同,后加一个回调函数。这种方法不会刷新页面,提高效率。只支持4.4+以上的系统
js 调用native方法
addJavascriptInterface
:webview 提供的可以让 js 调用 native 中的方法,如mwebView.addJavascriptInterface(new JSCallJava(this), 'caller')
,JSCallJava 就是java代码中提供给 js 调用的类,js 中可以通过caller.callJava
来调用。在早期版本中存在漏洞,攻击者可以通过 js 加载 java 中的反射类去执行本地命令,高版本中可以通过@JavascriptInter
进行规避传数据的两种方法:
shoulOverrideUrlLoading
:通过拦截 url 跳转来实现 js 调用 native 方法,通过自定义url 协议格式传数据,在这个WebViewClient
中的shouldOverrideUrlLoading
中拦截处理onJsxxx
系列:通过WebChromeClient
拦截js对话框实现对 native 调用,WebChromeClient
中存在三种弹框,分别是alert,confirm,prompt
,对应的方法为onJsAlert,onJsConfirm,onJsPrompt
。在 js 代码中执行相应的方法,通过约定的数据格式传递数据
JsBridge
native 和 h5 交互桥梁,内部实现还是通过 loadUrl 和 shouldOverrideUrlLoading 来实现 js 和 native 的互调。实际使用中需要用 BridgeWebView 替代 WebView,BridgeWebView 在 init 时会默认加载一个 BridgeWebViewClient,其中重写了 shouldOverrideUrlLoding 对从 js 传入的数据进行分发,在 onPageFinished 中将 WebViewJavaScriptBridge.js 加载到 html 页面中。
native 中调用 js
- send 方法:
mBridgeWebView.send(data, callback)
,可以设置回调接收从 js 中获取到的结果,send 会使用 js 中默认的handle处理 - 自定义方法 callHandle,native 中
mBridgeWebView.callHandle(handlerName, data, callback)
,js 中bridge.registerHandler(handleName, function(){})
js 调用 native
有 WebViewJavaScriptBridge.js 的封装,可以用类似步骤实现
- send:
window.WebViewJavascriptBridge.send(data, callback)
- callHandle:
window.WebViewJavaScriptBridge.callHandle(handleName, data, callback)
,在 native 中注册好 handlemBridge.registerHandle(handleName, callback)
参考