Android WebView JSBridge 的 Hybrid

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012246458/article/details/88794073

前言

Hybrid App,即混合开发,也就是半原生半Web的开发模式,有跨平台运行效果;

JSBridge是H5与Native通信的桥梁;

Git库

Android:JsBridge

iOS:WebViewJavascriptBridge

JsBridge解析

WebView相关的两个重要的类:WebViewClient和WebChromeClient。

WebViewClient:帮助WebView处理各种通知,事件请求,主要的方法有:onLoadResource,onPageStart, onPageFInish, onReceiveError, ShouldOverrideUrlLoading。

WebChromeClient:处理javascript的对话框,网页图标,网站title,加载进度条。主要方法有:onCreateWindow, OnCloseWindow, onJsAlert, onJsConfirm, onJsConsole, onProgressChanged, onReceiveIcon, onReceiveTitle.

要实现JAVA和JS通信,就要解决:1,java调js;2,js调java。这就是通过WebView的JsBridge

1、Java调js:通过loadUrl和evaluateJavascript两个方法:

loadUrl方法:例如通过webview.loadUrl(“javascript:alert(‘hello world’)”),可以将js代码注入到html页面执行。loadUrl可以直接调用js中的函数,也可以把android本地assets目录下的js文件读取到内存,获取字符串,直接把本地js文件注入到html页面,相当于在html页面中加载了一个本地js文件。对于客户端来说,和js的交互,本质上是拼接js字符串的过程,调用loadUrl不能直接获取js函数的返回值。

evaluateJavascript方法:和loadUrl方法类似,区别是:1,它可以获取调用的js函数的返回值;2,在android4.4以及上才可以使用。使用方法如下:

webview.evaluateJavascript(“javascript:alert(‘hello world’)”, new ValueCallback<String>(){

@Override

public void onReceiveValue(String value){

               System.out.println(“js函数返回值:” + value);

}

})。

需要注意的是一定要等onPageFinish完成了才能调用,否则有可能出现无法找到方法的错误。

2,Js调java:分三种:1,对象映射;2,URL拦截,3,方法拦截

1) 对象映射通过WebView的addJavascriptInterface方法把java对象映射到js对象,webview.addJavascriptInterface(new 

扫描二维码关注公众号,回复: 5656547 查看本文章

  JSObject(), “javaObject”),这样在js代码可以调用javaObject,就可以访问java代码。这个方法在android4.2以下有安全漏洞,利用addJavascriptInterface方法注册可供javascript调用的java对象,利用反射机制调用Android API getRuntime执行shell命令进行攻击,比如遍历sdcard,发送短信,安装木马APK等。

2)  URL拦截,通过WebViewClient的shouldOverrideUrlLoading方法,拦截js代码执行例如:“document.location=’js://webview?name=root&pwd=1234’”; 根据scheme(协议格式)和authority(协议名),获取name和pwd。Js可以触发WebviewClient的shouldOverrideUrlLoading方法有:1,document.loacation;  2,href;  3,window.open;4,iframe.src。

3)方法拦截,JS中执行对话框alert(警告框),prompt(提示框),confirm(确认框),console.log方法,可以触发WebChromClinet的onJsAlert,onJsPrompt,onJsConfirm,onConsoleMessage的回调。alert会弹出对话框, confirm确定对 话框,console是用来debug javascript代码的,一般prompt使用的频率比较小,使用prompt来进行js调用java。

JsBridge简单封装

如果自己不需要封装自己的JsBridge,那么就使用上面的Git库就可以了,原理基本上一样。

封装一个JsBridge框架

将js和java的通信封装起来可以按如下思路进行:JsBridge框架需要有一个本地的WebviewJsBridge.js文件和对应的java代码。Java和js各自定义一个json串的消息传递的Message数据结构,形式如下:

{data: “”,

 callbackId:””,

 handlerName:””,

 responseData:””,

 responseId:””

}

本地js文件主要逻辑:

var messageHandlers = [];  // 以键值对的形式存储js处理与java约定的handler方法
var responseCallbacks = [];  // 以键值对的形式存储js的回调函数
var defaultHandler;        // 默认处理java调用js的方法
doSend(handlerName, data, responseCallback) //通过iframe.src赋值,将”XYZ://_JS_BRIDGE_//message”传递给java(shouldOverrideUrlLoading回调),其中message根据定义的数据结构生成的一个json串。
function handleMessageFromNative(){} // 接受java传递过来的消息

自定义一个WebviewJsBridgeRead的Event,如果本地的webviewJsBridge加载完毕就做一些初始化工作,比如初始化默认的Handler。

Java代码:

HashMap<String, BridgeHandler> messageHandlers;     // js调用的java方法
HashMap<String, CallbackFunction> responseCallbacks;  // 发送消息给js后的java回调
BridgeHandler defaultHandler;   // 默认处理js调用java的方法
public void doSend(String handlerName, String data, CallbackFunction responseCallback){} // 通过webview.loadUrl(“javascript:// handleMessageFromNative(message)”),handleMessageFromNative。 

调用图:

js会收到java传递过来的消息Java主动发起调用js代码,message格式:{callbackId:JAVA_CB_1_1234,data:XXX,handlerName:null};java回调函数处理js带过来的responseData时序图:

Js主动发起调用java代码,message格式:{callbackId:JS_CB_1_1234,data:XXXX,handlerName:null};js回调函数处理java带过来的responseData时序图:

猜你喜欢

转载自blog.csdn.net/u012246458/article/details/88794073