来自Understanding Android's webview addjavascriptinterface:“WebView.addJavascriptInterface 方法向WebViewCore 的实例发送消息:
mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg); 在 WebViewCore.java 中有一堆称为 sendMessage 的重载方法,但我们并不需要知道究竟调用了哪些方法,因为它们的作用几乎相同。甚至有一个很好的评论给我们一个提示,我们在正确的地方!所有这些都委托给 EventHub 的一个实例,它是一些内部类。这个方法被证明是同步的,并且正在向 Handler 的实例发送消息,这很好地表明它可能在另一个线程中运行,但为了完整起见,让我们找出来!
该处理程序在从 WebViewCore.initialize 调用的 EventHub.transferMessages 中实例化。这里还有几跳,但最终我发现这是从WebCoreThread(Runnable的子类)中的run调用的,它在此处与一个新线程一起实例化。“在此处与一个新线程一起实例化。”
synchronized (WebViewCore.class) {
if (sWebCoreHandler == null) {
// Create a global thread and start it.
Thread t = new Thread(new WebCoreThread());
t.setName(THREAD_NAME);
t.start();
try {
WebViewCore.class.wait();
} catch (InterruptedException e) {
Log.e(LOGTAG, "Caught exception while waiting for thread " +
"creation.");
Log.e(LOGTAG, Log.getStackTraceString(e));
}
}
}
换句话说,在我看来,这可能是一系列调用:
android.webkit.WebViewClassic
4159 @Override
4160 public void More ...addJavascriptInterface(Object object, String name) {
4161
4162 if (object == null) {
4163 return;
4164 }
4165 WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
4166
4167 arg.mObject = object;
4168 arg.mInterfaceName = name;
4169
4170 // starting with JELLY_BEAN_MR1, annotations are mandatory for enabling access to
4171 // methods that are accessible from JS.
4172 if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
4173 arg.mRequireAnnotation = true;
4174 } else {
4175 arg.mRequireAnnotation = false;
4176 }
4177 mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
4178 }
android.webkit.WebViewCore
static class JSInterfaceData {
827 Object mObject;
828 String mInterfaceName;
829 boolean mRequireAnnotation;
830 }
java.lang.Object
37 public class Object {
38
39 private static native void registerNatives();
40 static {
41 registerNatives();
42 }
返回此 Object 的运行时类。返回的 Class 对象是被表示类的静态同步方法锁定的对象。实际结果类型是 Class where |X| 是调用 getClass 的表达式的静态类型的擦除。例如,此代码片段中不需要强制转换:
Number n = 0;
Class<? extends Number> c = n.getClass();
返回: 表示此对象的运行时类的 Class 对象。另请参阅:Java 语言规范,第三版(15.8.2 类文字)
64
65 public final native Class<?> getClass();
从 Dalvik 的角度来看,我认为您只是通过 findClass 从JNIHelp.c注册一个 JNI 回调:
/*
* Register native JNI-callable methods.
*
* "className" looks like "java/lang/String".
*/
int jniRegisterNativeMethods(JNIEnv* env, const char* className,
const JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
LOGV("Registering %s natives\n", className);
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
LOGE("Native registration unable to find class '%s', aborting\n",
className);
abort();
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
LOGE("RegisterNatives failed for '%s', aborting\n", className);
abort();
}
(*env)->DeleteLocalRef(env, clazz);
return 0;
}
总之,我的想法来自Native Libraries:
//Get jclass with env->FindClass
所以也许 FindClass 可以用来代替 getClass ......