Dalvik技術揭秘之二Dalvik虛擬機器的進入點

來源:互聯網
上載者:User

要分析Dalvik虛擬機器的代碼,到底從那裡開始比較好呢?從事軟體開發人員都知道,每個程式都有生命週期,都有出生點,也就是程式的進入位置。像C語言裡控制台程式是使用main函數作為進入點的,java程式也是使用main函數作為進入點。其實Dalvik虛擬機器作為應用程式啟動時,也是一樣的從main函數開始。從Dalvik虛擬機器源碼目錄dalvik/dalvikvm/Main.c檔案,就可以看到入口函數,如下:

/*

*Parse arguments. Most of it just gets passed through to the VM. The

*JNI spec defines a handful of standard arguments.

*/

intmain(int argc, char* const argv[])

{

JavaVM* vm = NULL;

JNIEnv* env = NULL;

JavaVMInitArgs initArgs;

JavaVMOption* options = NULL;

char* slashClass = NULL;

int optionCount, curOpt, i, argIdx;

int needExtra = JNI_FALSE;

int result = 1;

 

setvbuf(stdout, NULL, _IONBF, 0);

 

/* ignore argv[0] */

argv++;

argc--;

…...

 

因此,當你編譯Dalvik虛擬機器作為linux下x86應用程式來運行時,就需要注意了,這裡是它的入口。

 

也許你會問,為什麼需要Dalvik虛擬機器作為linux下x86應用程式運行,它不是在手機平台ARM裡啟動並執行嗎?這個問題問得好,問到點子上了。其實Dalvik虛擬機器作為linux下x86應用程式運行,是用來開發和調試使用的,當需要作為手機平台使用時,它不是從Main函數作為進入點。嵌入式的開發人員都知道,在一個資源有限平台裡開發和調試,都是一件不容易的事情,需要花費很多時間,那麼有沒有更好的方法來開發和調試呢?答案是有的。就是利用目前x86的平台,這樣可以使用x86大量的工具和資源,大大地提高開發效率,更容易調試系統的功能。在Dalvik虛擬機器進行開發新功能時,可以先在x86的平台上運行和調試通過,然後再編譯在ARM平台運行。我曾經修改這個虛擬機器的代碼後,再在系統裡編譯和運行,發覺剛剛編譯整個平台的時間,就非常多,在4核的CPU、4G記憶體的linux系統下,再利用make-j4等多核編譯技術,也需要好幾分鐘,這樣每修改幾行代碼,添加一些細小的功能,就需編譯測試一次,付出的時間成本太多了,顯然需要另找出路,那麼就是使用x86平台方式產生應用程式來測試。還有另外一個問題,就是單步調試的功能,在ARM平台也是比較麻煩的事情,程式有時會跑飛等等。

 

下面再來分析另外一個進入點,就是android的dalvik虛擬機器在ARM平台啟動並執行進入點。它顯然不會通過Main函數來載入的,而從初始化進程載入的服務Zygote開始的。從Zygote服務代碼,可以看到下面代碼:

runtime.start("com.android.internal.os.ZygoteInit",

startSystemServer);

這雷根據命令列參數來建立Dalvik虛擬機器,並從com.android.internal.os.ZygoteInit開始運行,然後啟動所有Dalvik虛擬服務。這這裡的runtime對象,就是類AppRuntime,而類AppRuntime繼承類AndroidRuntime,那麼類AndroidRuntime是何物呢?類AndroidRuntime是android平台核心架構裡的代碼,它是實現JNI的基石,也就是說所有Dalvik虛擬機器裡的應用程式要訪問底層系統的功能,都是通過JNI來實現的。可以從下面的檔案找到這個類:

frameworks/base/core/jni/AndroidRuntime.cpp

在這個檔案裡,可以看到上面調用函數start的實現,如下:

/*

*Start the Android runtime. This involves starting the virtualmachine

*and calling the "static void main(String[] args)" method inthe class

*named by "className".

*/

voidAndroidRuntime::start(const char* className, const boolstartSystemServer)

{

LOGD("/n>>>>>>>>>>>>>>AndroidRuntime START <<<<<<<<<<<<<</n");

 

char* slashClassName = NULL;

char* cp;

JNIEnv* env;

 

blockSigpipe();

 

/*

* 'startSystemServer == true' means runtimeis obslete and not run from

* init.rc anymore, so we print out the bootstart event here.

*/

if (startSystemServer) {

/* track our progress through the bootsequence */

const int LOG_BOOT_PROGRESS_START = 3000;

LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,

ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));

}

 

const char* rootDir =getenv("ANDROID_ROOT");

if (rootDir == NULL) {

rootDir = "/system";

if (!hasDir("/system")) {

LOG_FATAL("No root directoryspecified, and /android does not exist.");

goto bail;

}

setenv("ANDROID_ROOT", rootDir,1);

}

 

//const char* kernelHack =getenv("LD_ASSUME_KERNEL");

//LOGD("FoundLD_ASSUME_KERNEL='%s'/n", kernelHack);

 

/* start the virtual machine */

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

goto bail;

 

/*

* Register android functions.

*/

if (startReg(env) < 0) {

LOGE("Unable to register all androidnatives/n");

goto bail;

}

 

從上面的程式碼片段裡,可以看到調用函數startVm,這個函數就是建立Dalvik虛擬機器,繼續查看函數startVm的程式碼片段,可以發現下面一段:

/*

* Initialize the VM.

*

* The JavaVM* is essentially per-process,and the JNIEnv* is per-thread.

* If this call succeeds, the VM is ready,and we can start issuing

* JNI calls.

*/

LOGD("JNI_CreateJavaVM Start.../n");

if (JNI_CreateJavaVM(pJavaVM, pEnv,&initArgs) < 0) {

LOGE("JNI_CreateJavaVM failed/n");

goto bail;

}

LOGD("JNI_CreateJavaVM End/n");

 

result = 0;

 

在這段代碼裡,主要任務就是初始化Dalvik虛擬機器,通過調用JNI_CreateJavaVM函數來實現的,而JNI_CreateJavaVM函數的實現,就是在檔案Dalvik/vm/Jni.c裡。

 

到這裡,就已經把另一個進入點分析完成了,通過上面的學習可以知道不同的入口,是來源於現實開發的需要,通過這些大型代碼工程,可以學習到很多開發技巧,提高效率的方法。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.