Android源碼中很多關鍵代碼都是C++實現的,java通過jni來調用,經常會看到java中這樣的代碼:
static native Thread currentThread();
如何根據方法名找到其對應的C++實現,有兩個方法。
先來個java代碼的示例VMThread.java:
package java.lang; class VMThread { Thread thread; int vmData; VMThread(Thread t) { thread = t; } native static void create(Thread t, long stackSize); static native Thread currentThread(); static native boolean interrupted(); static native void sleep (long msec, int nsec) throws InterruptedException; static native void yield(); native void interrupt(); native boolean isInterrupted();
...... }
我們要查找currentThread方法的實現。
方法一:
由於Android源碼中對每個native實現都會寫一個java方法名和C++方法名映射的列表,所以我們直接搜索這個列表內容即可。
zkw@zkw $ grep -rns '"currentThread"' ./*
./art/compiler/dex/quick/dex_file_method_inliner.cc:108: "currentThread", // kNameCacheCurrentThread
匹配到二進制文件 ./dalvik/vm/native/.java_lang_VMThread.cpp.swp
./dalvik/vm/native/java_lang_VMThread.cpp:241: { "currentThread", "()Ljava/lang/Thread;",
./external/android-mock/tests/com/google/android/testing/mocking/AndroidMockGeneratorTest.java:249: Method method = Thread.class.getMethod("currentThread");
./external/android-mock/tests/com/google/android/testing/mocking/AndroidMockGeneratorTest.java:407: Method method = Thread.class.getMethod("currentThread");
可以看到,在文件./dalvik/vm/native/java_lang_VMThread.cpp中找到currentThread方法相關的信息,后面()Ljava/lang/Thread代表這個方法的返回值。
進入java_lang_VMThread.cpp這個文件可以看到:
17 /* 18 * java.lang.VMThread 19 */ 20 #include "Dalvik.h" 21 #include "native/InternalNativePriv.h" 22 23 24 /* 25 * static void create(Thread t, long stacksize) 26 * 27 * This is eventually called as a result of Thread.start(). 28 * 29 * Throws an exception on failure. 30 */ 31 static void Dalvik_java_lang_VMThread_create(const u4* args, JValue* pResult) 32 { 33 Object* threadObj = (Object*) args[0]; 34 s8 stackSize = GET_ARG_LONG(args, 1); 35 36 /* copying collector will pin threadObj for us since it was an argument */ 37 dvmCreateInterpThread(threadObj, (int) stackSize); 38 RETURN_VOID(); 39 } 40 41 /* 42 * static Thread currentThread() 43 */ 44 static void Dalvik_java_lang_VMThread_currentThread(const u4* args, 45 JValue* pResult) 46 { 47 UNUSED_PARAMETER(args); 48 49 RETURN_PTR(dvmThreadSelf()->threadObj); 50 } 51
......
237 238 const DalvikNativeMethod dvm_java_lang_VMThread[] = { 239 { "create", "(Ljava/lang/Thread;J)V", 240 Dalvik_java_lang_VMThread_create }, 241 { "currentThread", "()Ljava/lang/Thread;", 242 Dalvik_java_lang_VMThread_currentThread }, 243 { "getStatus", "()I", 244 Dalvik_java_lang_VMThread_getStatus }, 245 { "holdsLock", "(Ljava/lang/Object;)Z", 246 Dalvik_java_lang_VMThread_holdsLock }, 247 { "interrupt", "()V", 248 Dalvik_java_lang_VMThread_interrupt }, 249 { "interrupted", "()Z", 250 Dalvik_java_lang_VMThread_interrupted }, 251 { "isInterrupted", "()Z", 252 Dalvik_java_lang_VMThread_isInterrupted }, 253 { "nameChanged", "(Ljava/lang/String;)V", 254 Dalvik_java_lang_VMThread_nameChanged }, 255 { "setPriority", "(I)V", 256 Dalvik_java_lang_VMThread_setPriority }, 257 { "sleep", "(JI)V", 258 Dalvik_java_lang_VMThread_sleep }, 259 { "yield", "()V", 260 Dalvik_java_lang_VMThread_yield }, 261 { NULL, NULL, NULL }, 262 };
源碼中第242行找到對應的名字,用紅色標出,其實現就在第44行。
這個方法不是很准確,要靠經驗來判斷搜出來的代碼是否是自己要找的,下一個方法可以較准確的查找。
方法二:
還是找VMThread.java的currentThread函數,找多了會發現,C++的名字一般都是包名+類名+方法名,比如currentThread的C++名字就肯定包含“java_lang_VMThread_currentThread”,所以直接搜索即可。
grep -rns "java_lang_VMThread_currentThread" ./*