1. 程式人生 > >Android應用程式的程序建立過程

Android應用程式的程序建立過程

[toc] # 前言 我們知道當startActivity的時候,除了建立Activity相關實體,系統會根據需要是否建立程序,此程序就是指的Linux層面的程序實體;後面會說到,其實建立的過程是fork,意為從父程序“copy”出一個新的程序。此過程必定經歷啟動者、ams、zygote等相互的程序間通訊,本文主要梳理ams在此過程的重要環節,涉及虛擬機器的繼承、Binder執行緒池、訊息迴圈是怎麼建立的等等,而Activity的啟動細節則放在其他章節另作探討。 # 步驟 ## step1 Ams發起請求startProcessLocked *ActivityManagerService.java* 直接從Ams中向zygote發起請求的入口開始分析,當然真正的開始是Ams收到其他應用的Binder請求,所以應該在onTransact裡面才是真正的開始,待會兒會打出trace看。(這兒一個小細節,原始碼中有很多方法帶Locked字尾,說明使用該方法需要加鎖,因為其是非執行緒安全的)。 ``` // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + app.processName); checkTime(startTime, "startProcess: asking zygote to start proc"); Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs); checkTime(startTime, "startProcess: returned from zygote!"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); ``` 比較重要的是這一段話,呼叫Process類的start方法,並指定了入口類為ActivityThread。 ``` system 671 641 2348412 179992 0 0000000000 S Binder:641_1 641-671/system_process W: at android.os.Process.zygoteSendArgsAndGetResult(Process.java:605) 641-671/system_process W: at android.os.Process.startViaZygote(Process.java:738) 641-671/system_process W: at android.os.Process.start(Process.java:521) 641-671/system_process W: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4214) 641-671/system_process W: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4069) 641-671/system_process W: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3909) 641-671/system_process W: at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1441) 641-671/system_process W: at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2741) 641-671/system_process W: at com.android.server.am.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:2213) 641-671/system_process W: at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:1859) 641-671/system_process W: at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1393) 641-671/system_process W: at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:1237) 641-671/system_process W: at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:7393) 641-671/system_process W: at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:571) 641-671/system_process W: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3169) 641-671/system_process W: at android.os.Binder.execTransact(Binder.java:565) ``` 從如上的trace可以直接看出,在收到startActivity的請求後,執行了對當前Activity的pause操作,然後通過Process.java這個類對Zygote程序發起請求。注意,通過對執行緒號的觀察可以看到,這一切都在一次binder執行緒中操作的。 注意Ams與Zygote之間是通過socket連線的,封裝了zygoteState類去做通訊相關的任務。從下圖fd的佔用可以明確地看到,zygote程序是不使用binder的。 ``` device:/proc/341/fd # ls -l ls -l total 0 lrwx------ 1 root root 64 2021-03-16 17:49 0 -> /dev/null lrwx------ 1 root root 64 2021-03-16 17:49 1 -> /dev/null lr-x------ 1 root root 64 2021-03-16 17:49 10 -> /system/framework/core-oj.jar lr-x------ 1 root root 64 2021-03-16 17:49 11 -> /system/framework/core-libart.jar lr-x------ 1 root root 64 2021-03-16 17:49 12 -> /system/framework/conscrypt.jar lr-x------ 1 root root 64 2021-03-16 17:49 13 -> /system/framework/okhttp.jar lr-x------ 1 root root 64 2021-03-16 17:49 14 -> /system/framework/core-junit.jar lr-x------ 1 root root 64 2021-03-16 17:49 15 -> /system/framework/bouncycastle.jar lr-x------ 1 root root 64 2021-03-16 17:49 16 -> /system/framework/ext.jar lr-x------ 1 root root 64 2021-03-16 17:49 17 -> /system/framework/framework.jar lr-x------ 1 root root 64 2021-03-16 17:49 18 -> /system/framework/telephony-common.jar lr-x------ 1 root root 64 2021-03-16 17:49 19 -> /system/framework/voip-common.jar lrwx------ 1 root root 64 2021-03-16 17:49 2 -> /dev/null lr-x------ 1 root root 64 2021-03-16 17:49 20 -> /system/framework/ims-common.jar lr-x------ 1 root root 64 2021-03-16 17:49 21 -> /system/framework/apache-xml.jar lr-x------ 1 root root 64 2021-03-16 17:49 22 -> /system/framework/org.apache.http.legacy.boot.jar lrwx------ 1 root root 64 2021-03-16 17:49 23 -> socket:[9842] lr-x------ 1 root root 64 2021-03-16 17:49 24 -> /system/framework/framework-res.apk lr-x------ 1 root root 64 2021-03-16 17:49 25 -> /dev/urandom l-wx------ 1 root root 64 2021-03-16 17:49 5 -> /sys/kernel/debug/tracing/trace_marker lrwx------ 1 root root 64 2021-03-16 17:49 6 -> /dev/null lrwx------ 1 root root 64 2021-03-16 17:49 7 -> /dev/null lrwx------ 1 root root 64 2021-03-16 17:49 8 -> /dev/null lrwx------ 1 root root 64 2021-03-16 17:49 9 -> socket:[9289] ``` Ams的呼叫棧到上面就截止了,接下來進入到Zygote程序中。 ## step2 Zygote收到請求 猜想Zygote程序初始化完成後,一定有個無限迴圈在等待其他程序的請求,直接定位到程式碼。 ``` private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { A