在Android源碼, frameworks/base/core/jni/目錄下,有AndroidRuntime的源碼,編譯后生成libandroid_runtime.so,這個動態庫非常重要。
里面含有很多用c++寫的jni的方法,這些方法會被虛擬機上層java文件所調用,當我嘗試在其中找JNI_OnLoad函數時,卻沒有找到,通常jni開發時要在動態庫中導出這個函數,這樣用System.loadLibrary才能通過它來注冊jni的方法,於是我的疑惑來了。打開AndroidRuntime.cpp一看,里面有一行:
static const RegJNIRec gRegJNI[] = {
這是一個數組,包含了所有的文件里的jni方法的注冊過程,繼續找到一行:
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
說明register_jni_procs這個函數注冊了這個數組里的所有過程。這行語句包含在startReg里,再找到調用它的語句:
/*
* Register android functions.
*/
if (startReg(env) < 0) {
而這就是位於start函數中:
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*/
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
這個函數負責start一個類中的main函數的工作。
我的理解是先啟動虛擬機,然后注冊jni方法,給要運行的java class作准備,最后才執行java class里的main函數。
應該說libandroid_runtime.so方法不是一個標准的jni庫,而是特殊的jni庫,它不能在一般的java文件里被通過System.loadLibrary引入,
似乎可以通過davikvm的命令行來調用java類,在java類的文件main函數里動態載入libandroid_runtime.so,然后注冊jni方法
這可以通過frameworks/base/core/com/android/internal/util/WithFramework.java來分析
