package com.zenglb.baselib.jsbridge; import android.net.Uri; import android.text.TextUtils; import android.webkit.WebView; import org.json.JSONObject; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; /** * * */ public class JSBridge { public static String exposeClassName = "NativeBridgeClsName"; //所有JS能调用的native 的方法都需要注册,防止反编译后重新注入native方法 private static Map<String, HashMap<String, Method>> exposedMethods = new HashMap<>(); /** * 注入JS 可以调用的Native方法! * * @param exposedName * @param clazz */ 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 injectedCls * @return * @throws Exception */ private static HashMap<String, Method> getAllMethod(Class injectedCls) throws Exception { HashMap<String, Method> mMethodsMap = new HashMap<>(); Method[] methods = injectedCls.getDeclaredMethods(); for (Method method : methods) { String name; if (method.getModifiers() != (Modifier.PUBLIC | Modifier.STATIC) || (name = method.getName()) == null) { continue; } Class[] parameters = method.getParameterTypes(); if (null != parameters && parameters.length == 3) { if (parameters[0] == WebView.class && (parameters[1] == JSONObject.class || parameters[1] == Integer.class) && parameters[2] == Callback.class) { mMethodsMap.put(name, method); } } } return mMethodsMap; } /** * 需要处理没法调用的Native方法等问题 * * @param webView * @param uriString * @return */ public static String callJavaNative(WebView webView, String uriString) { String methodName = ""; String className = ""; String param = "{}"; String port = ""; if (!TextUtils.isEmpty(uriString) && uriString.startsWith("JSBridge")) { //如果不是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("/", ""); } } if (exposedMethods.containsKey(className)) { HashMap<String, Method> methodHashMap = exposedMethods.get(className); if (methodHashMap != null && methodHashMap.size() != 0) { Method method = methodHashMap.get(methodName); if (method != null) { try {//http://azrael6619.iteye.com/blog/429797 Java的反射机制 method.invoke(null, webView, new JSONObject(param), new Callback(webView, port)); } catch (Exception e) { e.printStackTrace(); } } else { Method eorMethod = methodHashMap.get("returnCommonEor"); //需要处理本地方法不存在的情况 try { eorMethod.invoke(null, webView, JSCallBackStatusCode.NATIVE_FUNCTION_NULL, new Callback(webView, port)); } catch (Exception e) { e.printStackTrace(); } } } } return null; } }