比较windows phone程序启动和android程序启动原理
?windows phone 程序是如何啟動的了,他和android程序有什么區(qū)別,我們重點從native code 層面來分析
?在windows phone 程序啟動的時候是:
在XAML中使用應(yīng)用程序定義指定起始Page(它是啟動 WindowsPhone7程序時自動加載的Page)。
指定方法是將 StartupUri 屬性設(shè)置為所需的 Page 的 統(tǒng)一資源標(biāo)識符 (URI)。
可以在標(biāo)記中以聲明方式設(shè)置 StartupUri,如下面的示例所示。
<Application
????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????x:Class="SDKSample.App"
????StartupUri="PageWithHyperlink.xaml"?/>
此例中,StartupUri 特性設(shè)置為標(biāo)識 HomePage.xaml 的相對 pack URI。當(dāng)WindowsPhone7 APP 啟動時,將自動導(dǎo)航到 HomePage.xaml 并顯示該文件。就是這個鳥樣:
至于android是如何啟動的,我這里要從native code 講起來。
首先,大家都知道android是linux內(nèi)核的,他的啟動自然離不開linux中的boothloader與kernel啟動,這里面我就不做過多的贅述。
下面都是android的從servicemanager里面來啟動相應(yīng)的后臺進(jìn)程,用zyngote來啟動daemon process。這個后臺進(jìn)程是用來使其程序得以維持,而daemon 這個守護(hù)進(jìn)程是對程序的狀況得以監(jiān)聽的。至于daemon process 在java上的應(yīng)用確實很多,譬如用apache 發(fā)布jsp的程序的時候,這個apache就是守護(hù)進(jìn)程。
?servicemanager這是c語言中定義,定義中的后臺的進(jìn)程,至于zynote這個進(jìn)程了,這是從app_main cp中來開啟一個initial方法對其初始化方法。
前面的關(guān)鍵字service告訴init進(jìn)程創(chuàng)建一個名為"zygote"的進(jìn)程,這個zygote進(jìn)程要執(zhí)行的程序是/system/bin/app_process,后面是要傳給app_process的參數(shù)。
?接下來的socket關(guān)鍵字表示這個zygote進(jìn)程需要一個名稱為"zygote"的socket資源,這樣,系統(tǒng)啟動后,我們就可以在/dev/socket目錄下看到有一個名為zygote的文件。這里定義的socket的類型為unix domain socket,它是用來作本地進(jìn)程間通信用的,具--基于socket的進(jìn)程間通信。前面我們說到的ActivityManagerService就是通這個socket來和zygote進(jìn)程通信請求fork一個應(yīng)用程序進(jìn)程的了。
?? ? ? ?最后的一系列onrestart關(guān)鍵字表示這個zygote進(jìn)程重啟時需要執(zhí)行的命令。
?? ? ? ?關(guān)于init.rc文件的更多信息,請參考system/core/init/readme.txt文件。
?? ? ? ?了解了這個信息之后,我們就知道Zygote進(jìn)程要執(zhí)行的程序便是system/bin/app_process了,它的源代碼位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函數(shù)是main。在繼續(xù)分析Zygote進(jìn)程啟動的過程之前,我們先來看看它的啟動序列圖:
?這是app_ain中的cpp源代碼:
?
int main(int argc, const char* const argv[]) { // These are global variables in ProcessState.cpp mArgC = argc; mArgV = argv; mArgLen = 0; for (int i=0; i<argc; i++) { mArgLen += strlen(argv[i]) + 1; } mArgLen--; AppRuntime runtime; const char *arg; argv0 = argv[0]; // Process command line arguments // ignore argv[0] argc--; argv++; // Everything up to '--' or first non '-' arg goes to the vm int i = runtime.addVmArguments(argc, argv); // Next arg is parent directory if (i < argc) { runtime.mParentDir = argv[i++]; } // Next arg is startup classname or "--zygote" if (i < argc) { arg = argv[i++]; if (0 == strcmp("--zygote", arg)) { bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false; setArgv0(argv0, "zygote"); set_process_name("zygote"); runtime.start("com.android.internal.os.ZygoteInit", startSystemServer); } else { set_process_name(argv0); runtime.mClassName = arg; // Remainder of args get passed to startup class main() runtime.mArgC = argc-i; runtime.mArgV = argv+i; LOGV("App process is starting with pid=%d, class=%s.\n", getpid(), runtime.getClassName()); runtime.start(); } } else { LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); return 10; } }我們驚奇的看到了start了zynote.cs 文件,?? 這個就是開啟了zynote進(jìn)程,這個就是當(dāng)前守護(hù)進(jìn)程的初始化。那么這個zynote.cpp是什么了?
我們看其中AndroidRuntime的源代碼:
這個androidRunTime,是cpp文件, 是通過jnt方式用java來訪問c++的源代碼,這是android能夠調(diào)用linux kernel中的關(guān)鍵性的技術(shù)。
?
這就是我對android 中的啟動理解。
???這個函數(shù)的作用是啟動Android系統(tǒng)運行時庫,它主要做了三件事情,一是調(diào)用函數(shù)startVM啟動虛擬機(jī),二是調(diào)用函數(shù)startReg注冊JNI方法,三是調(diào)用了com.android.internal.os.ZygoteInit類的main函數(shù)。
?它主要作了三件事情,一個調(diào)用registerZygoteSocket函數(shù)創(chuàng)建了一個socket接口,用來和ActivityManagerService通訊,二是調(diào)用startSystemServer函數(shù)來啟動SystemServer組件,三是調(diào)用runSelectLoopMode函數(shù)進(jìn)入一個無限循環(huán)在前面創(chuàng)建的socket接口上等待ActivityManagerService請求創(chuàng)建新的應(yīng)用程序進(jìn)程。
這個socket接口是通過文件描述符來創(chuàng)建的,這個文件描符代表的就是我們前面說的/dev/socket/zygote文件了。這個文件描述符是通過環(huán)境變量ANDROID_SOCKET_ENV得到的,它定義為:
????????那么,這個環(huán)境變量的值又是由誰來設(shè)置的呢?我們知道,系統(tǒng)啟動腳本文件system/core/rootdir/init.rc是由init進(jìn)程來解釋執(zhí)行的,而init進(jìn)程的源代碼位于system/core/init目錄中,在init.c文件中,是由service_start函數(shù)來解釋init.rc文件中的service命令的:
每一個service命令都會促使init進(jìn)程調(diào)用fork函數(shù)來創(chuàng)建一個新的進(jìn)程,在新的進(jìn)程里面,會分析里面的socket選項,對于每一個socket選項,都會通過create_socket函數(shù)來在/dev/socket目錄下創(chuàng)建一個文件,在這個場景中,這個文件便是zygote了,然后得到的文件描述符通過publish_socket函數(shù)寫入到環(huán)境變量中去:
???????因此,這里就把上面得到的文件描述符寫入到以"ANDROID_SOCKET_zygote"為key值的環(huán)境變量中。又因為上面的ZygoteInit.registerZygoteSocket函數(shù)與這里創(chuàng)建socket文件的create_socket函數(shù)是運行在同一個進(jìn)程中,因此,上面的ZygoteInit.registerZygoteSocket函數(shù)可以直接使用這個文件描述符來創(chuàng)建一個Java層的LocalServerSocket對象。如果其它進(jìn)程也需要打開這個/dev/socket/zygote文件來和Zygote進(jìn)程進(jìn)行通信,那就必須要通過文件名來連接這個LocalServerSocket了,參考4,ActivityManagerService是通過Process.start函數(shù)來創(chuàng)建一個新的進(jìn)程的,而Process.start函數(shù)會首先通過Socket連接到Zygote進(jìn)程中,最終由Zygote進(jìn)程來完成創(chuàng)建新的應(yīng)用程序進(jìn)程,而Process類是通過openZygoteSocketIfNeeded函數(shù)來連接到Zygote進(jìn)程中的Socket的:
這是我對android理解,這能夠?qū)Υ蠹規(guī)韼椭?/p>
好好學(xué)習(xí),天天向上。
總結(jié)
以上是生活随笔為你收集整理的比较windows phone程序启动和android程序启动原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mdadm 设置管理
- 下一篇: HDU 4628 Pieces(DP +