比较windows phone程序启动和android程序启动原理
?windows phone 程序是如何啟動(dòng)的了,他和android程序有什么區(qū)別,我們重點(diǎn)從native code 層面來分析
?在windows phone 程序啟動(dòng)的時(shí)候是:
在XAML中使用應(yīng)用程序定義指定起始Page(它是啟動(dòng) WindowsPhone7程序時(shí)自動(dòng)加載的Page)。
指定方法是將 StartupUri 屬性設(shè)置為所需的 Page 的 統(tǒng)一資源標(biāo)識(shí)符 (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)識(shí) HomePage.xaml 的相對(duì) pack URI。當(dāng)WindowsPhone7 APP 啟動(dòng)時(shí),將自動(dòng)導(dǎo)航到 HomePage.xaml 并顯示該文件。就是這個(gè)鳥樣:
至于android是如何啟動(dòng)的,我這里要從native code 講起來。
首先,大家都知道android是linux內(nèi)核的,他的啟動(dòng)自然離不開linux中的boothloader與kernel啟動(dòng),這里面我就不做過多的贅述。
下面都是android的從servicemanager里面來啟動(dòng)相應(yīng)的后臺(tái)進(jìn)程,用zyngote來啟動(dòng)daemon process。這個(gè)后臺(tái)進(jìn)程是用來使其程序得以維持,而daemon 這個(gè)守護(hù)進(jìn)程是對(duì)程序的狀況得以監(jiān)聽的。至于daemon process 在java上的應(yīng)用確實(shí)很多,譬如用apache 發(fā)布jsp的程序的時(shí)候,這個(gè)apache就是守護(hù)進(jìn)程。
?servicemanager這是c語言中定義,定義中的后臺(tái)的進(jìn)程,至于zynote這個(gè)進(jìn)程了,這是從app_main cp中來開啟一個(gè)initial方法對(duì)其初始化方法。
前面的關(guān)鍵字service告訴init進(jìn)程創(chuàng)建一個(gè)名為"zygote"的進(jìn)程,這個(gè)zygote進(jìn)程要執(zhí)行的程序是/system/bin/app_process,后面是要傳給app_process的參數(shù)。
?接下來的socket關(guān)鍵字表示這個(gè)zygote進(jìn)程需要一個(gè)名稱為"zygote"的socket資源,這樣,系統(tǒng)啟動(dòng)后,我們就可以在/dev/socket目錄下看到有一個(gè)名為zygote的文件。這里定義的socket的類型為unix domain socket,它是用來作本地進(jìn)程間通信用的,具--基于socket的進(jìn)程間通信。前面我們說到的ActivityManagerService就是通這個(gè)socket來和zygote進(jìn)程通信請(qǐng)求fork一個(gè)應(yīng)用程序進(jìn)程的了。
?? ? ? ?最后的一系列onrestart關(guān)鍵字表示這個(gè)zygote進(jìn)程重啟時(shí)需要執(zhí)行的命令。
?? ? ? ?關(guān)于init.rc文件的更多信息,請(qǐng)參考system/core/init/readme.txt文件。
?? ? ? ?了解了這個(gè)信息之后,我們就知道Zygote進(jìn)程要執(zhí)行的程序便是system/bin/app_process了,它的源代碼位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函數(shù)是main。在繼續(xù)分析Zygote進(jìn)程啟動(dòng)的過程之前,我們先來看看它的啟動(dòng)序列圖:
?這是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 文件,?? 這個(gè)就是開啟了zynote進(jìn)程,這個(gè)就是當(dāng)前守護(hù)進(jìn)程的初始化。那么這個(gè)zynote.cpp是什么了?
我們看其中AndroidRuntime的源代碼:
這個(gè)androidRunTime,是cpp文件, 是通過jnt方式用java來訪問c++的源代碼,這是android能夠調(diào)用linux kernel中的關(guān)鍵性的技術(shù)。
?
這就是我對(duì)android 中的啟動(dòng)理解。
???這個(gè)函數(shù)的作用是啟動(dòng)Android系統(tǒng)運(yùn)行時(shí)庫(kù),它主要做了三件事情,一是調(diào)用函數(shù)startVM啟動(dòng)虛擬機(jī),二是調(diào)用函數(shù)startReg注冊(cè)JNI方法,三是調(diào)用了com.android.internal.os.ZygoteInit類的main函數(shù)。
?它主要作了三件事情,一個(gè)調(diào)用registerZygoteSocket函數(shù)創(chuàng)建了一個(gè)socket接口,用來和ActivityManagerService通訊,二是調(diào)用startSystemServer函數(shù)來啟動(dòng)SystemServer組件,三是調(diào)用runSelectLoopMode函數(shù)進(jìn)入一個(gè)無限循環(huán)在前面創(chuàng)建的socket接口上等待ActivityManagerService請(qǐng)求創(chuàng)建新的應(yīng)用程序進(jìn)程。
這個(gè)socket接口是通過文件描述符來創(chuàng)建的,這個(gè)文件描符代表的就是我們前面說的/dev/socket/zygote文件了。這個(gè)文件描述符是通過環(huán)境變量ANDROID_SOCKET_ENV得到的,它定義為:
????????那么,這個(gè)環(huán)境變量的值又是由誰來設(shè)置的呢?我們知道,系統(tǒng)啟動(dòng)腳本文件system/core/rootdir/init.rc是由init進(jìn)程來解釋執(zhí)行的,而init進(jìn)程的源代碼位于system/core/init目錄中,在init.c文件中,是由service_start函數(shù)來解釋init.rc文件中的service命令的:
每一個(gè)service命令都會(huì)促使init進(jìn)程調(diào)用fork函數(shù)來創(chuàng)建一個(gè)新的進(jìn)程,在新的進(jìn)程里面,會(huì)分析里面的socket選項(xiàng),對(duì)于每一個(gè)socket選項(xiàng),都會(huì)通過create_socket函數(shù)來在/dev/socket目錄下創(chuàng)建一個(gè)文件,在這個(gè)場(chǎng)景中,這個(gè)文件便是zygote了,然后得到的文件描述符通過publish_socket函數(shù)寫入到環(huán)境變量中去:
???????因此,這里就把上面得到的文件描述符寫入到以"ANDROID_SOCKET_zygote"為key值的環(huán)境變量中。又因?yàn)樯厦娴腪ygoteInit.registerZygoteSocket函數(shù)與這里創(chuàng)建socket文件的create_socket函數(shù)是運(yùn)行在同一個(gè)進(jìn)程中,因此,上面的ZygoteInit.registerZygoteSocket函數(shù)可以直接使用這個(gè)文件描述符來創(chuàng)建一個(gè)Java層的LocalServerSocket對(duì)象。如果其它進(jìn)程也需要打開這個(gè)/dev/socket/zygote文件來和Zygote進(jìn)程進(jìn)行通信,那就必須要通過文件名來連接這個(gè)LocalServerSocket了,參考4,ActivityManagerService是通過Process.start函數(shù)來創(chuàng)建一個(gè)新的進(jìn)程的,而Process.start函數(shù)會(huì)首先通過Socket連接到Zygote進(jìn)程中,最終由Zygote進(jìn)程來完成創(chuàng)建新的應(yīng)用程序進(jìn)程,而Process類是通過openZygoteSocketIfNeeded函數(shù)來連接到Zygote進(jìn)程中的Socket的:
這是我對(duì)android理解,這能夠?qū)Υ蠹規(guī)韼椭?/p>
好好學(xué)習(xí),天天向上。
總結(jié)
以上是生活随笔為你收集整理的比较windows phone程序启动和android程序启动原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mdadm 设置管理
- 下一篇: HDU 4628 Pieces(DP +