package com.camnter.newlife.ui.activity.jsbridge;
import android.net.Uri;
import android.text.TextUtils;
import android.webkit.WebView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
/**
* 协议: JsBridge://className:callbackAddress/methodName?jsonObject
*
* Js 层通过 WebChromeClient 的 onJsPrompt, onJsAlert, onJsConfirm 回调方法
* 调用到 JsBridge 方法去反射调用 native 逻辑代码
*
* Description:JsBridge
* Created by:CaMnter
*/
public final class JsBridge {
private static Map<String, HashMap<String, Method>> exposedMethods = new HashMap<>();
public static void register(String exposedName, Class<? extends IBridge> clazz) {
if (!exposedMethods.containsKey(exposedName)) {
try {
exposedMethods.put(exposedName, getAllMethod(clazz));
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 反射获取 一个类的 所有方法
*
* @param injectClass 目标类
* @return 所有方法键值对 < 方法名, 方法 >
*/
private static HashMap<String, Method> getAllMethod(Class injectClass) {
HashMap<String, Method> methodHashMap = new HashMap<>();
Method[] methods = injectClass.getDeclaredMethods();
for (Method method : methods) {
String methodName;
if (method.getModifiers() != (Modifier.PUBLIC | Modifier.STATIC) ||
(methodName = method.getName()) == null) {
continue;
}
Class[] parameters = method.getParameterTypes();
if (parameters != null && parameters.length == 3) {
if (parameters[0] == WebView.class && parameters[1] == JSONObject.class &&
parameters[2] == JsCallback.class) {
methodHashMap.put(methodName, method);
}
}
}
return methodHashMap;
}
/**
* 协议: JsBridge://className:callbackAddress/methodName?jsonObject
*
* Js 层通过 WebChromeClient.onJsPrompt(...) 等方法调用到 native 层的 callJava 方法
*
* @param webView WebView
* @param uriString 协议
*/
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();
port = uri.getPort() + "";
param = uri.getQuery();
String path = uri.getPath();
if (!TextUtils.isEmpty(path)) {
methodName = path.replace("/", "");
}
}
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) {
return null;
}
try {
method.invoke(null, webView, new JSONObject(param),
new JsCallback(webView, port));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return null;
}
}