from Understanding the Android interface addjavascriptinterface : "The WebView.addJavascriptInterface method sends a message to the WebViewCore instance:
mWebViewCore.sendMessage (EventHub.ADD_JS_INTERFACE, arg); There are many overloaded methods in WebViewCore.java called sendMessage, but we donβt need to know what exactly is being called, because they do almost the same thing. There is even a good comment to give us a hint that we are in the right place! They all delegate an instance of EventHub, which is some inner class. This method turns out to be synchronized and sends a message to the Handler instance, which is a good indication that it probably works in a different thread, but for completeness, let's find out!
This handler is created in EventHub.transferMessages, which is called from WebViewCore.initialize. There are a few more jumps here, but in the end I found out that it was called from a run in WebCoreThread (a subclass of Runnable), which is created along with a new thread right here. "Created with the new stream right here."
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)); } } }
In other words, it could be a chain of calls, in my opinion:
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
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 }
Returns the execution class of this object. The returned class object is an object that is locked by the static synchronized methods of the presented class. The actual type of result is the class where | X | is erasing the static type of the expression on which getClass is invoked. For example, a throw is not required in this code fragment:
Number n = 0; Class<? extends Number> c = n.getClass();
Returns: a class object that represents the runtime class of this object. See Also: Java Language Specification, Third Edition (15.8.2 Class Literals)
64 65 public final native Class<?> getClass();
From the point of view of Dalvik, I think you are just registering a JNI callback through findClass, like this from JNIHelp.c :
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; }
In conclusion, my idea is derived from Native Libraries :
so maybe FindClass can be used instead of getClass ...