一、常用通信方式JavascriptInterface
JavascriptInterface这个比较常见不多说了
二、通过
JSBridge
这种方式主要是为了实现前端异步调用native方法,并回传数据
思路也就是 h5-->android, android--->h5,
消息回传:
"javascript:JSBridge.onFinish('%s', %s);"
wx.showToast({ 'msg': 'Hello JSBridge' }, function (res) {
alert(JSON.stringify(res))
})
主要代码如下:
1.js实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Carson</title>
<script>
var callbacks = {};
var getParam = function (obj) {
if (obj && typeof obj === 'object') {
return JSON.stringify(obj);
} else {
return obj || '';
}
}
var getPort = function () {
return Math.floor(Math.random() * (1 << 30));
}
var JSBridge = {
call: function (className, method, params, callback) {
var port = getPort();
callbacks[port] = callback;
var uri = 'jsbridge://' + className + ':' + port + '/' + method + '?' + getParam(params);
window.prompt(uri, "");
}
onFinish: function (port, jsonObj) {
var callback = callbacks[port];
callback && callback(jsonObj);
delete callbacks[port];
}
}
JSBridge.onPayFinished = function(res){
alert(JSON.stringify(res))
}
var wx = {
showToast: function(param, callback) {
JSBridge.call('NativeApi', 'showToast', param, callback);
}
}
// <!--由于对象映射,所以调用test对象等于调用Android映射的对象-->
var callAndroid = function () {
// 下面会调用java中的 bridge.showToast方法
wx.showToast({ 'msg': 'Hello JSBridge' }, function (res) {
alert(JSON.stringify(res))
})
}
</script>
</head>
<body>
<!--点击按钮则调用callAndroid函数-->
<button type="button" id="button1"
style="width: 500px; height: 100px; font-size:40px; margin-left:40px; margin-top:60px;"
onclick="callAndroid()">点击调用Android中方法
</button>
</body>
</html>
2.android
webview启动后注册接口,这里注册主要是为了把方法加入容器,h5调用时候可以找到:
JSBridge.register(NativeApi.class.getSimpleName(), NativeApi.class);
webview 设置接口client:
private JSBridgeWebChromeClient webChromeClient = new JSBridgeWebChromeClient();
webview.setWebChromeClient(webChromeClient);
public class JSBridgeWebChromeClient extends WebChromeClient {
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
result.confirm(JSBridge.callJava(view, message));
return true;
}
}
主要通过prompt获取数据,并处理:JSBridge.callJava(view, message)
callJava方法中有一个反射,通过h5传递过来的类、方法、参数、端口进行反射到具体方法,具体方法处理后,根据port调用固定的"javascript:JSBridge.onFinish('%s', %s);",传递回h5端口及参数
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import com.tencent.smtt.sdk.WebView;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
/**
* js通信异步方式
*/
public class JSBridge {
private static Map<String, HashMap<String, Method>> exposedMethods = new HashMap<>();
private static Map<String, Object> exposedObjects = new HashMap<>();
/**
* 注册
*
* @param exposedName className
* @param clazz class
*/
public static void register(String exposedName, Class<? extends ICallBack> clazz) {
if (!exposedMethods.containsKey(exposedName)) {
try {
exposedMethods.put(exposedName, getAllMethod(clazz));
exposedObjects.put(exposedName, clazz.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static HashMap<String, Method> getAllMethod(Class injectedCls) throws Exception {
HashMap<String, Method> mMethodsMap = new HashMap<>();
Method[] methods = injectedCls.getDeclaredMethods();
for (Method method : methods) {
int Modifiers = method.getModifiers();
if (Modifiers == Modifier.PUBLIC) {
String name = method.getName();
mMethodsMap.put(name, method);
}
}
return mMethodsMap;
}
// 调用java逻辑
public static String callJava(WebView webView, String uriString) {
String methodName = "";
String className = "";
String param = "{}";
String port = "";
if (!TextUtils.isEmpty(uriString) && uriString.startsWith("jsbridge")) {
Uri uri = Uri.parse(uriString);
className = uri.getHost();
param = uri.getQuery();
port = uri.getPort() + "";
String path = uri.getPath();
if (!TextUtils.isEmpty(path)) {
methodName = path.replace("/", "");
}
//jsbridge://className:callbackAddress/methodName?jsonObj
// 基于上面的className、methodName和port path调用对应类的方法
if (exposedMethods.containsKey(className)) {
HashMap<String, Method> methodHashMap = exposedMethods.get(className);
if (methodHashMap != null && methodHashMap.size() != 0 && methodHashMap.containsKey(methodName)) {
Method method = methodHashMap.get(methodName);
if (method != null) {
try {
Object o = exposedObjects.get(className);
method.invoke(o, webView, param, new Callback(webView, port));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
// 上述程序的callback.apply方法实现如下: 即通过webView.loadUrl实现java调用js的方法
public static class Callback {
private static Handler mHandler = new Handler(Looper.getMainLooper());
private static final String CALLBACK_JS_FORMAT = "javascript:JSBridge.onFinish('%s', %s);";
private String mPort;
private WeakReference<WebView> mWebViewRef;
public Callback(WebView view, String port) {
mWebViewRef = new WeakReference<>(view);
mPort = port;
}
public void apply(JSONObject jsonObject) {
final String execJs = String.format(CALLBACK_JS_FORMAT, mPort, String.valueOf(jsonObject));
if (mWebViewRef != null && mWebViewRef.get() != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
mWebViewRef.get().loadUrl(execJs);
}
});
}
}
}
}
import org.json.JSONObject;
/**
* js callback 父类
*/
public class ICallBack {
public JSONObject getJSONObject(int code, String success, JSONObject object) {
try {
JSONObject obj = new JSONObject();
obj.put("code", code + "");
obj.put("success", success);
obj.put("data", object);
return obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void dealCallback(JSBridge.Callback callback, JSONObject object) {
try {
callback.apply(getJSONObject(0, "ok", object));
} catch (Exception e) {
e.printStackTrace();
}
}
public void successCallBack(JSBridge.Callback callback) {
if (null != callback) {
try {
JSONObject object = new JSONObject();
object.put("status", true);
dealCallback(callback, object);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void failCallBack(JSBridge.Callback callback) {
if (null != callback) {
try {
JSONObject object = new JSONObject();
object.put("status", true);
dealCallback(callback, object);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
import org.json.JSONObject;
/**
* js通信异步方式-数据处理
*/
public class NativeApi extends ICallBack {
// 直接进入showToast函数的实现
public void showToast(WebView webView, String message, final JSBridge.Callback callback) {
Toast.makeText(webView.getContext(), message, Toast.LENGTH_SHORT).show();
if (null != callback) {
try {
JSONObject object = new JSONObject();
object.put("key1", "value1");
dealCallback(callback, object);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}