Android中webview与native之间的交互方式(jsbridge)
来源:互联网 发布:手机视频慢放软件 编辑:程序博客网 时间:2024/06/01 09:03
Android中webview与native之间的交互方式(jsbridge)
前言
随着H5的广泛使用,Android开发过程中免不了会使用网页来做展示,那么,web与native之间的通信就显得尤其重要了,其实际上是JavaScript与java之间的通信;如图所示,我们开发过程中需要在native中调用JavaScript,或者是在JavaScript中调用native。
* JavaScript调用java
JavaScript调用java的方式可以分为两类,一是通过捕获url scheme的方式,二是利用原生接口实现调用。
1. 捕获url scheme的方式
核心思想是:web端与native首先协商好通信中使用的url的格式,紧接着web端通过一定的方式将url发送出去,最后native层捕获url,并进行分析后再去调用原生方法。这种方法也是目前被广泛使用的方式。
a) 首先第一步是约定好url的格式,例如这里约定为:
JSBridge://bridge:129129723/showToast?{"msg":"Hello JSBridge"}
其中showToast为需要调用的native层方法,{“msg”:”Hello JSBridge”}为向native传递的json数据。
b) 约定好传递格式后,web端需要触发native层去捕获url。
Android中为我们提供了两个类WebViewClient和WebChromeClient,这两个类分别为我们提供了一些方法可以使用。当有任何url在webview中使用时都会被WebViewClient的shouldOverrideUrlLoading函数拦截,因此我们可以利用这个特性,在JavaScript中构建一个1像素的iframe来触发这个函数。web端代码如下:
var url = 'JSBridge://bridge:129129723/showToast?{"msg":"Hello JSBridge"}';
var iframe = document.createElement('iframe');
iframe.style.width = '1px';
iframe.style.height = '1px';
iframe.style.display = 'none';
iframe.src = url;
document.body.appendChild(iframe);
Android端代码:
webView = (WebView) findViewById(R.id.webView);
webView.setVerticalScrollbarOverlay(true);
//设置WebView支持JavaScript
webView.getSettings().setJavaScriptEnabled(true);
String url = "file:///android_asset/test.html"; //加载本地html
webView.loadUrl(url);
webView.setWebViewClient(new JsbridgeWebViewClient());
其中JsbridgeWebViewClient继承WebViewClient,并重写shouldOverrideUrlLoading方法,并在里面实现调用原生方法的逻辑。
其次,WebChromeClient提供了三个原生的方法,当在JavaScript中使用window.alert,window.confirm,window.prompt三个方法时会相应的触发WebChromeClient对象的onJsPrompt、onJsAlert、onJsConfirm方法,所以我们也可以在前端通过这三种方式触发native捕获url。web端代码如下:
var url = 'JSBridge://bridge:129129723/showToast?{"msg":"Hello JSBridge"}';
window.prompt(uri, "");
Android端代码只要将上面的JsbridgeWebViewClient继承WebChromeClient ,并重写onJsPrompt、onJsAlert、onJsConfirm方法即可,这里就不再重复。
c) native层捕获到url后,如何调用?
通过解析url,可以得到需要调用的native方法名以及json数据;这里举例是调用native层的showToast方法,我采用反射的方式来进行调用,核心代码:
“`
public static void showToast(WebView webView, JSONObject param) {
String message = param.optString(“msg”);
Toast.makeText(webView.getContext(), message, Toast.LENGTH_SHORT).show();
}
public static String callJava(WebView webView, String uriString, Object owner) {
String methodName = “”;
String className = “”;
String param = “{}”;
String port = “”;
if (!TextUtils.isEmpty(uriString) && uriString.startsWith(“jsbridge”)) {
Uri uri = Uri.parse(uriString);//解析url
className = uri.getHost();
param = uri.getQuery();
port = uri.getPort() + “”;
String path = uri.getPath();
if (!TextUtils.isEmpty(path)) {
methodName = path.replace(“/”, “”);
}
}
Class classType = owner.getClass();
Method showToastMethod = null;
try {
showToastMethod = classType.getMethod(methodName,new Class[]{WebView.class,JSONObject.class});
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
showToastMethod.invoke(owner, webView, new JSONObject(param));//反射调用showToast方法
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
“`
以上是通过捕获url scheme实现JavaScript调用java的方式。
**2. 使用原生方法 **addJavascriptInterface
Android为我们提供了addJavascriptInterface方法,JavaScript可以直接调用java方法,但该方法在Android 4.2以下是存在安全隐患的,可参考,官方在Android4.2进行了修复,在使用addJavascriptInterface方法时,必须在提供给JavaScript调用的方法前添加@JavascriptInterface。例如在Android端将showInfoFromJs和getInfoFromJs提供给js调用:
private class JsInterface { private Context mContext; public JsInterface(Context context) { this.mContext = context; } //在js中调用window.test.showInfoFromJs(name),便会触发此方法。 @JavascriptInterface public void showInfoFromJs(String name) { Toast.makeText(mContext, name, Toast.LENGTH_SHORT).show(); } @JavascriptInterface public void getInfoFromJs(int a, int b){ int c = a+b; Toast.makeText(mContext, ""+c, Toast.LENGTH_SHORT).show(); }}
//设置WebView支持JavaScriptwebView.getSettings().setJavaScriptEnabled(true);String url = "file:///android_asset/test.html";webView.loadUrl(url);//在js中调用本地java方法webView.addJavascriptInterface(new JsInterface(this), "test");
在js中通过以下进行调用:
var name = document.getElementById("name_input").value;var a = 1;var b = 2;window.test.showInfoFromJs(name);window.test.getInfoFromJs(a,b);
java调用JavaScript
java调用javascript的方法比较简单,因为android为我们提供了相应的方法, 4.4之前通过loadUrl的方式,而在4.4之后提供了evaluateJavascrip异步调用的方式。这里就只举例loadurl的方法。
String msg = ((EditText) findViewById(R.id.input_et)).getText().toString();//调用js中的函数:showInfoFromJava(msg)webView.loadUrl("javascript:showInfoFromJava('" + msg + "')");
以上就是js与java互相调用的方式。
- Android中webview与native之间的交互方式(jsbridge)
- WebView Native与H5交互—jsbridge
- JsBridge android中java与js交互
- Android中WebView的JavaScript-native交互
- Android webView与js 交互以及jsbridge框架源码分析
- Android JSBridge实现与前端的交互
- android 中webView与Activity之间的交互
- Android-使用JsBridge来优化js与本地webview的交互
- Android WebView与javaScript之间的交互
- Android WebView和Native交互的3种方式总结
- android与js交互-jsbridge
- Android WebView与 JS 的交互方式
- WebView---Android中webview和js之间的交互
- WebView---Android中webview和js之间的交互
- Android-使用JsBridge来优化js与本地的交互
- Android利用JSBridge与HTML5的交互使用
- Android中WebView与Javascript的交互
- Android中WebView与JS的交互
- 剑指offer---桟的压入、弹出序列
- 软件工程造价师认证培训
- 微信公众号开发之如何接入微信的SDK(二)
- Visual Studio Code 提示"use the 'php.validate.executablePath'setting to configure the location of 'php
- spark streaming 的textFileStream读取不了数据原因分析
- Android中webview与native之间的交互方式(jsbridge)
- 46、java常用类-Date
- Python yield 使用浅析
- jar包添加到本地maven库
- jvm cpu100% 问题分析
- Read-only file system
- [模式分类] Parzen窗概率密度估计与Kn近邻概率密度估计
- 47、java常用类-DateFormat
- Nodejs 学习笔记之循环与闭包