圖片轉自http://blog.jobbole.com/67931/
一, 主要流程
- BootLoader引導,加載內核
- 內核模塊啓動init進程
- init進程掛載目錄,解析init.rc配置文件,fork一個zygote進程
- zygote進程創建虛擬機,創建serverSocket,fork一個systemServer進程
- systemServer啓動和註冊AMS、PMS、WMS等service到serviceManager裏,最後啓動系統界面
二, init進程
內核模塊啓動init進程(http://androidxref.com/source/xref/system/core/init/init.c)後,init進程掛載目錄,init_parse_config_file(“/init.rc”)解析init.rc配置文件(system/core/rootdir/init.rc),啓動服務和進程
- servicemanager:管理其他所有binder service,註冊添加服務,獲取服務
- zygote
- media: add AudioFlinger,AudioPolicyService,MediaPlayerService and CameraService to servicemanager
- bootanim(開機動畫和鈴聲)等其他服務
init.rc裏啓動zygote進程的語句是
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
上述語句規定了zygote的進程名、zygote之後要啓動system_server進程、zygote要創建一個權限660的socket
init_rc中有個語句是class_start main,執行的是 /system/core/init/builtins.c的do_class_start函數,它會執行service_start_if_not_disabled,即執行init.c的service_start函數,fork出一個子進程,調用execve函數來執行/system/bin/app_process,即執行
app_main.cpp的main函數
三, zygote進程
- app_main.cpp的main函數裏初始化和啓動Android運行時
運行時啓動的時候會創建虛擬機VM,然後調用com.android.internal.os.ZygoteInit.java中的main函數初始化zygote
- registerZygoteSocket():爲zygote命令連接註冊一個serverSocket,賦值給全局變量sServerSocket
- preload():預加載classes和resources
- startSystemServer():通過Zygote.forkSystemServer()方法fork一個子進程
runSelectLoopMode():無限循環,在前邊創建的sServerSocket上監聽連接請求。
fds.add(sServerSocket.getFileDescriptor());
fds是一個socket的文件描述符列表,sServerSocket的文件描述符保存在fds裏。
fdArray = fds.toArray(fdArray); index = selectReadable(fdArray);
selectReadable函數如果返回0,說明有客戶端的連接請求,sServerSocket通過accpet返回一個和客戶端通信的socket,保存在ZygoteConnection對象裏,將相應的文件描述符添加到fds裏面,select輪詢的下一次也會監聽這個socket了
if (index == 0) { ZygoteConnection newPeer = acceptCommandPeer(); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } private static ZygoteConnection acceptCommandPeer() { return new ZygoteConnection(sServerSocket.accept()); } index大於0時 { boolean done; done = peers.get(index).runOnce(); if (done) { peers.remove(index); fds.remove(index); } }
如果 selectReadable返回的數據大於0,說明有客戶端的數據請求。調用index索引對應的ZygoteConnection對象的runOnce函數fork一個子進程。
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName);
(上述過程也就是Zygote處理一次AMS請求的過程)
四, SystemServer進程
startSystemServer()方法裏,通過Zygote.forkSystemServer函數fork出了一個systemServer進程.
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
pid爲0的代碼塊,是新的systemServer進程要執行的代碼,即調用handleSystemServerProcess函數,代碼如下。
closeServerSocket();
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
由於systemServer進程是對zygote進程的fork,也就繼承了zygote進程的serverSocket,但systemServer進程其實不需要zygote進程的serverSocket,所以這裏就關閉了zygote進程裏的serverSocket。
然後在RuntimeInit.zygoteInit裏
commonInit();//初始化時區設置、Http UserAgent等
nativeZygoteInit();
applicationInit(targetSdkVersion, argv);
- commonInit()初始化時區設置、Http UserAgent等
- nativeZygoteInit()是調用com_android_internal_os_RuntimeInit_nativeZygoteInit,即調用了 app_main.cpp 中的 AppRuntime類的onZygoteInit(),啓動了Binder線程池。
applicationInit()函數調用invokeStaticMain,拋出ZygoteInit.MethodAndArgsCaller異常,然後被ZygoteInit.java的main函數裏被捕獲到
catch (MethodAndArgsCaller caller) { caller.run();
}
在run裏調用mMethod.invoke(null, new Object[] { mArgs });
我們是從startSystemServer()函數進來的,當時註明了“com.android.server.SystemServer”的參數,因此這裏就反射調用了com.android.server.SystemServer的main()函數- main()裏開始初始化工作
- System.loadLibrary(“android_servers”); 加載一個叫android_servers的本地庫(libandroid_servers.so文件:系統服務組件:和Android中實現的JNI)
- init1,這是個native方法,位於/frameworks/base/services/jni/com_android_server_SystemServer.cpp
其中調用了system_init();位於 /frameworks/base/cmds/system_server/library/system_init.cpp,初始化了SurfaceFlinger服務(負責繪製Android應用程序的UI)、sensorservice傳感器服務。然後回調了SystemServer.java裏的init2 - init2,啓動了一個ServerThread()
- Looper.prepareMainLooper();準備主線程Looper,創建UI用的HandlerThread
- 向ServiceManager裏添加各種Service,如PackageManagerService、ActivityManagerService、 ContentService、WindowManagerService、InputMethodManagerService等
- 調用 ActivityManagerService.self().systemReady函數,它調用了startSystemUi(contextF);啓動了系統界面。