Android——Dalvik虛擬機器運行ZygoteInit類

來源:互聯網
上載者:User

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

從上一節可以知道Dalvik虛擬機器進入點和建立虛擬機器的函數,這一節繼續分析運行時類調用虛擬機器的程式碼片段,需要搞清楚怎麼樣運行JAVA的ZygoteInit類,Dalvik虛擬機器又提供什麼樣的介面調用。運行時類代碼如下:

/* start the virtual machine */

if (startVm(&mJavaVM, &env) != 0)

goto bail;

這一段是建立虛擬機器,並準備好所有運行dex代碼的環境。

 

/*

* Register android functions.

*/

if (startReg(env) < 0) {

LOGE("Unable to register all android natives");

goto bail;

}

這一段是註冊所有android提供的本地方法,所謂的本地方法,其實是相對於JAVA裡定義的方法,比如像C或C++等提供二進位啟動並執行方法。

 

 

/*

* We want to call main() with a String array with arguments in it.

* At present we only have one argument, the class name. Create an

* array to hold it.

*/

jclass stringClass;

jobjectArray strArray;

jstring classNameStr;

jstring startSystemServerStr;

 

stringClass = env->FindClass("java/lang/String");

assert(stringClass != NULL);

strArray = env->NewObjectArray(2, stringClass, NULL);

assert(strArray != NULL);

classNameStr = env->NewStringUTF(className);

assert(classNameStr != NULL);

env->SetObjectArrayElement(strArray, 0, classNameStr);

startSystemServerStr = env->NewStringUTF(startSystemServer ?

"true" : "false");

env->SetObjectArrayElement(strArray, 1, startSystemServerStr);

這一段代碼主要作用是把型別參數className轉換為虛擬機器裡調用方法的參數,就是轉為 strArray數組表示,同時可以添加多個參數。

 

 

/*

* Start VM. This thread becomes the main thread of the VM, and will

* not return until the VM exits.

*/

jclass startClass;

jmethodID startMeth;

 

slashClassName = strdup(className);

這一行代碼是拷貝類名稱。

 

for (cp = slashClassName; *cp != ; cp++)

if (*cp == .)

*cp = /;

這一段代碼是把類名稱 com.android.internal.os.ZygoteInit轉換為 com/android/internal/os/ZygoteInit,為什麼要轉換這樣的方式呢?其實仔細思考一下,發現這不正是linux下的目錄表示方式嗎?是的,就是把類的點串連符變換為目錄方式,這要就可以到相應的目錄裡找到執行的代碼檔案。

 

LOGD("caijs add: JavaVM load class %s", slashClassName);

startClass = env->FindClass(slashClassName);

if (startClass == NULL) {

LOGE("JavaVM unable to locate class %s", slashClassName);

/* keep going */

} else {

這一段代碼主要通過類目錄結構com/android/internal/os/ZygoteInit,尋找到類的代碼,尋找到了就儲存在startClass變數裡。到這裡,已經接觸到Dalvik虛擬機器提供了最重要的一個方法,它就是 FindClass方法介面,這個介面比較強大,只要提供類的目錄結構,就可以找到相應的執行代碼,這樣就可以找類相關的方法入口,才可以給虛擬機器解譯器執行。因此,後面要好好瞭解和分析這個介面的實現。

 

 

startMeth = env->GetStaticMethodID(startClass, "main",

"([Ljava/lang/String;)V");

if (startMeth == NULL) {

LOGE("JavaVM unable to find main() in %s", className);

/* keep going */

} else {

這一段代碼是尋找方法進入點的ID。主要就是在前面找到的類代碼基礎之上,然後通過方法名稱“main”調用GetStaticMethodID介面,尋找到方法的ID。這個方法ID是給後面虛擬機器運行這個方法使用的,因為一個類裡有很多方法,每個方法都有一個ID,只有通過這個ID才可以找到相應的方法來運行。在這段代碼裡,有一個特別的地方,就是 GetStaticMethodID方法最後一個參數“([Ljava/lang/String;)V”。這個參數是一個字串,但內容排列比較奇怪,其實它是一種對函數傳回值和參數的編碼。這種編碼叫做JNI欄位描述符(Java Native Interface Field Descriptors)。

 

 

LOGD("caijs add: JavaVM find main() in %s", className);

env->CallStaticVoidMethod(startClass, startMeth, strArray);

這一行代碼主要調用虛擬機器的介面CallStaticVoidMethod 來運行 com.android.internal.os.ZygoteInit類裡的main方法。在Android系統裡,運行這個類代碼之後,就不再返回來了,這個進程就變成虛擬機器的主進程,這個虛擬機器就變成主要運行ZygoteInit類的虛擬機器了,其它應用程式的虛擬機器都是從這個虛擬複製出來,以達到快速地產生派生的虛擬機器,每個應用程式一個虛擬機器的健壯性、安全性。

 

#if 0

if (env->ExceptionCheck())

threadExitUncaughtException(env);

#endif

}

}

 

LOGD("Shutting down VM");

if (mJavaVM->DetachCurrentThread() != JNI_OK)

LOGW("Warning: unable to detach main thread");

if (mJavaVM->DestroyJavaVM() != 0)

LOGW("Warning: VM did not shut down cleanly");

這一段代碼是關閉所有虛擬機器時調用,基本上不會調用這段代碼的。

 

bail:

free(slashClassName);

這一行代碼是初始化出錯時調用。

 

}

 

在一節裡,學習了Davlik虛擬機器三大介面函數:FindClass、GetStaticMethodID和 CallStaticVoidMethod。其實理解起來很簡單,就是通過FindClass介面尋找到相應的Java類代碼,然後在這個類代碼用GetStaticMethodID介面尋找到相應的方法ID,最後通過 CallStaticVoidMethod介面運行相應的方法代碼,就完成Java代碼進入虛擬機器運行了。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.