App启动流程
目錄介紹
-
1.什么是Zygote進程
- 1.1 簡單介紹
- 1.2 各個進程的先后順序
- 1.3 進程作用說明
-
2.Zygote進程的啟動流程
- 2.1 源碼位置
- 2.2 ZygoteInit類的main方法
- 2.3 registerZygoteSocket(socketName)分析
- 2.4 preLoad()方法分析
- 2.5 startSystemServer()啟動進程
-
3.SystemServer進程啟動流程
- 3.1 SystemServer進程簡介
- 3.2 SystemServer的main方法
- 3.3 查看run方法
- 3.4 run方法中createSystemContext()解析
- 3.5 mSystemServiceManager的創(chuàng)建
-
4.啟動服務(wù)
- 4.1 啟動哪些服務(wù)
- 4.2 啟動服務(wù)流程源碼分析
- 4.3 啟動部分服務(wù)
好消息
- 博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識點,Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長期更新維護并且修正,持續(xù)完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計47篇[近20萬字],轉(zhuǎn)載請注明出處,謝謝!
- 鏈接地址:https://github.com/yangchong2...
- 如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬事起于忽微,量變引起質(zhì)變!
1.什么是Zygote進程
1.1 簡單介紹
- Zygote進程是所有的android進程的父進程,包括SystemServer和各種應(yīng)用進程都是通過Zygote進程fork出來的。Zygote(孵化)進程相當(dāng)于是android系統(tǒng)的根進程,后面所有的進程都是通過這個進程fork出來的
- 雖然Zygote進程相當(dāng)于Android系統(tǒng)的根進程,但是事實上它也是由Linux系統(tǒng)的init進程啟動的。
1.2 各個進程的先后順序
- init進程 --> Zygote進程 --> SystemServer進程 -->各種應(yīng)用進程
1.3 進程作用說明
- init進程:linux的根進程,android系統(tǒng)是基于linux系統(tǒng)的,因此可以算作是整個android操作系統(tǒng)的第一個進程;
- Zygote進程:android系統(tǒng)的根進程,主要作用:可以作用Zygote進程fork出SystemServer進程和各種應(yīng)用進程;
- SystemService進程:主要是在這個進程中啟動系統(tǒng)的各項服務(wù),比如ActivityManagerService,PackageManagerService,WindowManagerService服務(wù)等等;
- 各種應(yīng)用進程:啟動自己編寫的客戶端應(yīng)用時,一般都是重新啟動一個應(yīng)用進程,有自己的虛擬機與運行環(huán)境;
2.Zygote進程的啟動流程
2.1 源碼位置
- 位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
-
Zygote進程mian方法主要執(zhí)行邏輯:
- 初始化DDMS;
- 注冊Zygote進程的socket通訊;
- 初始化Zygote中的各種類,資源文件,OpenGL,類庫,Text資源等等;
- 初始化完成之后fork出SystemServer進程;
- fork出SystemServer進程之后,關(guān)閉socket連接;
2.2 ZygoteInit類的main方法
-
init進程在啟動Zygote進程時一般都會調(diào)用ZygoteInit類的main方法,因此這里看一下該方法的具體實現(xiàn)(基于android23源碼);
- 調(diào)用enableDdms(),設(shè)置DDMS可用,可以發(fā)現(xiàn)DDMS啟動的時機還是比較早的,在整個Zygote進程剛剛開始要啟動額時候就設(shè)置可用。
- 之后初始化各種參數(shù)
- 通過調(diào)用registerZygoteSocket方法,注冊為Zygote進程注冊Socket
- 然后調(diào)用preload方法實現(xiàn)預(yù)加載各種資源
- 然后通過調(diào)用startSystemServer開啟SystemServer服務(wù),這個是重點
2.3 registerZygoteSocket(socketName)分析
-
調(diào)用registerZygoteSocket(String socketName)為Zygote進程注冊socket
private static void registerZygoteSocket(String socketName) {if (sServerSocket == null) {int fileDesc;final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;try {String env = System.getenv(fullSocketName);fileDesc = Integer.parseInt(env);} catch (RuntimeException ex) {throw new RuntimeException(fullSocketName + " unset or invalid", ex);}try {FileDescriptor fd = new FileDescriptor();fd.setInt$(fileDesc);sServerSocket = new LocalServerSocket(fd);} catch (IOException ex) {throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex);}} }
2.4 preLoad()方法分析
-
源碼如下所示
static void preload() {Log.d(TAG, "begin preload");preloadClasses();preloadResources();preloadOpenGL();preloadSharedLibraries();preloadTextResources();// Ask the WebViewFactory to do any initialization that must run in the zygote process,// for memory sharing purposes.WebViewFactory.prepareWebViewInZygote();Log.d(TAG, "end preload"); } -
大概操作是這樣的:
- preloadClasses()用于初始化Zygote中需要的class類;
- preloadResources()用于初始化系統(tǒng)資源;
- preloadOpenGL()用于初始化OpenGL;
- preloadSharedLibraries()用于初始化系統(tǒng)libraries;
- preloadTextResources()用于初始化文字資源;
- prepareWebViewInZygote()用于初始化webview;
2.5 startSystemServer()啟動進程
-
這段邏輯的執(zhí)行邏輯就是通過Zygote fork出SystemServer進程
private static boolean startSystemServer(String abiList, String socketName)throws MethodAndArgsCaller, RuntimeException {long capabilities = posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND,OsConstants.CAP_KILL,OsConstants.CAP_NET_ADMIN,OsConstants.CAP_NET_BIND_SERVICE,OsConstants.CAP_NET_BROADCAST,OsConstants.CAP_NET_RAW,OsConstants.CAP_SYS_MODULE,OsConstants.CAP_SYS_NICE,OsConstants.CAP_SYS_RESOURCE,OsConstants.CAP_SYS_TIME,OsConstants.CAP_SYS_TTY_CONFIG);/* Hardcoded command line to start the system server */String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007","--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server","--runtime-args","com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {parsedArgs = new ZygoteConnection.Arguments(args);ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);/* Request to fork the system server process */pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}/* For child process */if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}handleSystemServerProcess(parsedArgs);}return true; }
3.SystemServer進程啟動流程
3.1 SystemServer進程簡介
- SystemServer進程主要的作用是在這個進程中啟動各種系統(tǒng)服務(wù),比如ActivityManagerService,PackageManagerService,WindowManagerService服務(wù),以及各種系統(tǒng)性的服務(wù)其實都是在SystemServer進程中啟動的,而當(dāng)我們的應(yīng)用需要使用各種系統(tǒng)服務(wù)的時候其實也是通過與SystemServer進程通訊獲取各種服務(wù)對象的句柄的。
3.2 SystemServer的main方法
- 如下所示,比較簡單,只是new出一個SystemServer對象并執(zhí)行其run方法,查看SystemServer類的定義我們知道其實final類型的,所以我們一般不能重寫或者繼承。
3.3 查看run方法
-
代碼如下所示
- 首先判斷系統(tǒng)當(dāng)前時間,若當(dāng)前時間小于1970年1月1日,則一些初始化操作可能會處所,所以當(dāng)系統(tǒng)的當(dāng)前時間小于1970年1月1日的時候,設(shè)置系統(tǒng)當(dāng)前時間為該時間點。
- 然后是設(shè)置系統(tǒng)的語言環(huán)境等
- 接著設(shè)置虛擬機運行內(nèi)存,加載運行庫,設(shè)置SystemServer的異步消息
-
然后下面的代碼是:
// Initialize the system context. createSystemContext();// Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// Start services. try {startBootstrapServices();startCoreServices();startOtherServices(); } catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex; }
3.4 run方法中createSystemContext()解析
-
調(diào)用createSystemContext()方法:
- 可以看到在SystemServer進程中也存在著Context對象,并且是通過ActivityThread.systemMain方法創(chuàng)建context的,這一部分的邏輯以后會通過介紹Activity的啟動流程來介紹,這里就不在擴展,只知道在SystemServer進程中也需要創(chuàng)建Context對象。
3.5 mSystemServiceManager的創(chuàng)建
- 看run方法中,通過SystemServiceManager的構(gòu)造方法創(chuàng)建了一個新的SystemServiceManager對象,我們知道SystemServer進程主要是用來構(gòu)建系統(tǒng)各種service服務(wù)的,而SystemServiceManager就是這些服務(wù)的管理對象。
-
然后調(diào)用:
- 將SystemServiceManager對象保存SystemServer進程中的一個數(shù)據(jù)結(jié)構(gòu)中。
-
最后開始執(zhí)行:
// Start services. try {startBootstrapServices();startCoreServices();startOtherServices(); } catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex; }-
里面主要涉及了是三個方法:
- startBootstrapServices() 主要用于啟動系統(tǒng)Boot級服務(wù)
- startCoreServices() 主要用于啟動系統(tǒng)核心的服務(wù)
- startOtherServices() 主要用于啟動一些非緊要或者是非需要及時啟動的服務(wù)
-
4.啟動服務(wù)
4.1 啟動哪些服務(wù)
- 在開始執(zhí)行啟動服務(wù)之前總是會先嘗試通過socket方式連接Zygote進程,在成功連接之后才會開始啟動其他服務(wù)。
4.2 啟動服務(wù)流程源碼分析
-
首先看一下startBootstrapServices方法:
private void startBootstrapServices() {Installer installer = mSystemServiceManager.startService(Installer.class);mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);mActivityManagerService.initPowerManagement();// Manages LEDs and display backlight so we need it to bring up the display.mSystemServiceManager.startService(LightsService.class);// Display manager is needed to provide display metrics before package manager// starts up.mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);// We need the default display before we can initialize the package manager.mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);// Only run "core" apps if we're encrypting the device.String cryptState = SystemProperties.get("vold.decrypt");if (ENCRYPTING_STATE.equals(cryptState)) {Slog.w(TAG, "Detected encryption in progress - only parsing core apps");mOnlyCore = true;} else if (ENCRYPTED_STATE.equals(cryptState)) {Slog.w(TAG, "Device encrypted - only parsing core apps");mOnlyCore = true;}// Start the package manager.Slog.i(TAG, "Package Manager");mPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);mFirstBoot = mPackageManagerService.isFirstBoot();mPackageManager = mSystemContext.getPackageManager();Slog.i(TAG, "User Service");ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());// Initialize attribute cache used to cache resources from packages.AttributeCache.init(mSystemContext);// Set up the Application instance for the system process and get started.mActivityManagerService.setSystemProcess();// The sensor service needs access to package manager service, app ops// service, and permissions service, therefore we start it after them.startSensorService(); } -
先執(zhí)行:
Installer installer = mSystemServiceManager.startService(Installer.class); -
mSystemServiceManager是系統(tǒng)服務(wù)管理對象,在main方法中已經(jīng)創(chuàng)建完成,這里我們看一下其startService方法的具體實現(xiàn):
- 可以看到通過反射器構(gòu)造方法創(chuàng)建出服務(wù)類,然后添加到SystemServiceManager的服務(wù)列表數(shù)據(jù)中,最后調(diào)用了service.onStart()方法,因為傳遞的是Installer.class
-
看一下Installer的onStart方法:
- 很簡單就是執(zhí)行了mInstaller的waitForConnection方法,這里簡單介紹一下Installer類,該類是系統(tǒng)安裝apk時的一個服務(wù)類,繼承SystemService(系統(tǒng)服務(wù)的一個抽象接口),需要在啟動完成Installer服務(wù)之后才能啟動其他的系統(tǒng)服務(wù)。
-
然后查看waitForConnection()方法:
- 通過追蹤代碼可以發(fā)現(xiàn),其在不斷的通過ping命令連接Zygote進程(SystemServer和Zygote進程通過socket方式通訊,其他進程通過Binder方式通訊)
-
繼續(xù)看startBootstrapServices方法:
- 這段代碼主要是用于啟動ActivityManagerService服務(wù),并為其設(shè)置SysServiceManager和Installer。ActivityManagerService是系統(tǒng)中一個非常重要的服務(wù),Activity,service,Broadcast,contentProvider都需要通過其余系統(tǒng)交互。
-
首先看一下Lifecycle類的定義:
- 可以看到其實ActivityManagerService的一個靜態(tài)內(nèi)部類,在其構(gòu)造方法中會創(chuàng)建一個ActivityManagerService,通過剛剛對Installer服務(wù)的分析我們知道,SystemServiceManager的startService方法會調(diào)用服務(wù)的onStart()方法,而在Lifecycle類的定義中我們看到其onStart()方法直接調(diào)用了mService.start()方法,mService是Lifecycle類中對ActivityManagerService的引用
4.3 啟動部分服務(wù)
-
啟動PowerManagerService服務(wù):
- 啟動方式跟上面的ActivityManagerService服務(wù)相似都會調(diào)用其構(gòu)造方法和onStart方法,PowerManagerService主要用于計算系統(tǒng)中和Power相關(guān)的計算,然后決策系統(tǒng)應(yīng)該如何反應(yīng)。同時協(xié)調(diào)Power如何與系統(tǒng)其它模塊的交互,比如沒有用戶活動時,屏幕變暗等等。
-
然后是啟動LightsService服務(wù)
- 主要是手機中關(guān)于閃光燈,LED等相關(guān)的服務(wù);也是會調(diào)用LightsService的構(gòu)造方法和onStart方法;
-
然后是啟動DisplayManagerService服務(wù)
- 主要是手機顯示方面的服務(wù)
-
然后是啟動PackageManagerService,該服務(wù)也是android系統(tǒng)中一個比較重要的服務(wù)
- 包括多apk文件的安裝,解析,刪除,卸載等等操作。
- 可以看到PackageManagerService服務(wù)的啟動方式與其他服務(wù)的啟動方式有一些區(qū)別,直接調(diào)用了PackageManagerService的靜態(tài)main方法
-
看一下其main方法的具體實現(xiàn):
- 可以看到也是直接使用new的方式創(chuàng)建了一個PackageManagerService對象,并在其構(gòu)造方法中初始化相關(guān)變量,最后調(diào)用了ServiceManager.addService方法,主要是通過Binder機制與JNI層交互
-
然后查看startCoreServices方法:
- 可以看到這里啟動了BatteryService(電池相關(guān)服務(wù)),UsageStatsService,WebViewUpdateService服務(wù)等。
總結(jié):
- SystemServer進程是android中一個很重要的進程由Zygote進程啟動;
- SystemServer進程主要用于啟動系統(tǒng)中的服務(wù);
- SystemServer進程啟動服務(wù)的啟動函數(shù)為main函數(shù);
- SystemServer在執(zhí)行過程中首先會初始化一些系統(tǒng)變量,加載類庫,創(chuàng)建Context對象,創(chuàng)建SystemServiceManager對象等之后才開始啟動系統(tǒng)服務(wù);
- SystemServer進程將系統(tǒng)服務(wù)分為三類:boot服務(wù),core服務(wù)和other服務(wù),并逐步啟動
- SertemServer進程在嘗試啟動服務(wù)之前會首先嘗試與Zygote建立socket通訊,只有通訊成功之后才會開始嘗試啟動服務(wù);
- 創(chuàng)建的系統(tǒng)服務(wù)過程中主要通過SystemServiceManager對象來管理,通過調(diào)用服務(wù)對象的構(gòu)造方法和onStart方法初始化服務(wù)的相關(guān)變量;
- 服務(wù)對象都有自己的異步消息對象,并運行在單獨的線程中;
參考博客
- https://www.jianshu.com/p/064...
- http://blog.csdn.net/qq_23547...
- http://www.xuebuyuan.com/2178...
- https://www.jianshu.com/p/e69...
- http://blog.csdn.net/luosheng...
- http://blog.csdn.net/ericming...
關(guān)于其他內(nèi)容介紹
01.關(guān)于博客匯總鏈接
- 1.技術(shù)博客匯總
- 2.開源項目匯總
- 3.生活博客匯總
- 4.喜馬拉雅音頻匯總
- 5.其他匯總
02.關(guān)于我的博客
- 我的個人站點:www.yczbj.org,www.ycbjie.cn
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/...
- 簡書:http://www.jianshu.com/u/b7b2...
- csdn:http://my.csdn.net/m0_37700275
- 喜馬拉雅聽書:http://www.ximalaya.com/zhubo...
- 開源中國:https://my.oschina.net/zbj161...
- 泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...
- 郵箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
- segmentfault頭條:https://segmentfault.com/u/xi...
總結(jié)
- 上一篇: 第四章:集成
- 下一篇: Socket SSL通讯