騰訊精選面試重點問題:Android源碼分析--應用程序啓動

面試官:什麼是應用程序啓動

應用程序的啓動,又可稱爲根Activity的啓動。但是在講應用程序啓動之前,我們有必要對應用程序進程(AppProcess)啓動有所瞭解,那是因爲啓動一個應用程序首先要保證該應用程序的進程已經被啓動。AMS在啓動應用程序時,會先檢查應用程序進程是否存在,如果不存在就需要請求Zygote進程創建並啓動應用程序進程。這裏我不會貼上大段大段的代碼,只是一些總結,並提供了相關源碼的鏈接。

應用程序進程(AppProcess)啓動

啓動大綱

  1. AMS發送啓動應用程序進程請求.
  2. Zygote接收請求並創建應用程序進程.

AMS發送啓動應用程序進程請求

騰訊精選面試重點問題:Android源碼分析--應用程序啓動

  • AMS通過調用startProcessLocked方法向Zygote進程發送請求。

  • Process調用start方法,使用ZygoteProcess的start方法。

  • 在ZygoteProcess的start方法中,先後調用了startViaZygotezygoteSendArgsAndGetResultopenZygoteSocketIfNeeded等方法,最後在openZygoteSocketIfNeeded方法中調用了ZygoteState的connect方法建立與Zygote進程的連接。

AMS發送啓動應用程序進程請求

騰訊精選面試重點問題:Android源碼分析--應用程序啓動

  • ZygoteServer執行runSelectLoop方法,一直等待AMS的請求數據到來。

  • 當AMS請求到來,與Zygote進程建立連接後,由ZygoteConnection的processOneCommand方法處理請求的數據。對請求數據進行解析,獲取程序進程的啓動參數,並通過Zygote的forkAndSpecialize方法進行應用程序進程的創建。

  • 進程創建完成後,交由ZygoteInit的zygoteInit方法和RuntimeInit的applicationInit方法分別進行進程和應用的初始化。在zygoteInit方法中,爲應用程序進程創建了Binder線程池,這樣進程就可以跨進程進行通信了。而applicationInit方法通過反射最終會調用ActivityThread的main方法,從而完成應用程序進程的創建。

    • *

應用程序(App)啓動

講完了應用程序進程(AppProcess)啓動的相關內容後,接下來我們就來看看應用程序是如何一步一步啓動的。

啓動大綱

  1. Launcher請求AMS。
  2. AMS請求ApplicationThread。
  3. ActivityThread啓動Activity。

啓動時序圖

騰訊精選面試重點問題:Android源碼分析--應用程序啓動

Launcher請求AMS

騰訊精選面試重點問題:Android源碼分析--應用程序啓動

  • 當我們點擊應用程序的圖標時,就會自動調用Launcher的startActivitySafely方法, 最終會調用Activity的startActivity方法。

  • 在Activity的startActivity中又調用了startActivityForResult方法,而startActivityForResult方法內部又調用了Instrumentation的execStartActivity方法。

  • 在Instrumentation的execStartActivity方法中又通過ActivityManager的getService方法獲取了IBinder類型的AMS引用IActivityManager,最後調用了AMS的startActivity方法。

AMS請求ApplicationThread

騰訊精選面試重點問題:Android源碼分析--應用程序啓動

  • 在AMS的startActivity方法中,又調用了其本身的startActivityAsUser方法,進行權限的檢查。

  • 權限檢查完後,調用ActivityStarter的startActivityMayWait方法,並在該方法中解析處理應用程序需要的參數,並進行相關參數的初始化,最終會調用其startActivity方法。而在startActivity方法中又調用了startActivityUnchecked方法來處理與棧管理相關的邏輯。

  • 在處理完棧的關係後,緊接着會調用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法獲取需要啓動的Activity所在棧的棧頂。

  • 當需要啓動的Activity的狀態不是RESUMED狀態,就需要調用ActivityStack的resumeTopActivityUncheckedLocked方法,而它的內部又調用了resumeTopActivityInnerLocked方法進行一系列的棧狀態的判斷,最終又回調了ActivityStackSupervisor的startSpecificActivityLocked方法。

  • 在ActivityStackSupervisor的startSpecificActivityLocked方法中先是獲取了即將啓動的Activity所在的應用程序進程(就是在這個地方判斷應用所在進程是否存在且已啓動,如果沒有啓動,就需要啓動應用程序進程),然後調用realStartActivityLocked方法。

  • 在ActivityStackSupervisor的realStartActivityLocked方法中,對啓動的應用程序進程進行一系列的判斷和處理,最終會調用IBinder類型的ApplicationThread引用IApplicationThread,通過傳入IApplicationThread建立ClientTransaction,加入執行LaunchActivityItem任務,最終實現跨進程執行調用ActivityThread的handleLaunchActivity方法。

ActivityThread啓動Activity

騰訊精選面試重點問題:Android源碼分析--應用程序啓動

  • 在ActivityThread調用了它的handleLaunchActivity方法中,會先調用其performLaunchActivity方法,之後調用handleResumeActivity,將Activity的狀態置爲Resume。

  • 在ActivityThread的performLaunchActivity方法中做了很多事情。
  1. 首先,執行了createBaseContextForActivity方法,創建要啓動Activity的上下文;
  2. 其次,調用執行了Instrumentation的newActivity方法來創建Activity實例;
  3. 接着,調用LoadedApk的makeApplication方法,創建應用程序的Application;
  4. 之後,調用需要啓動的Activity的attach方法初始化Activity,創建Window對象並與Activity自身進行關聯。
  5. 最後,調用執行了Instrumentation的callActivityOnCreate方法來啓動Activity。
  • 在Instrumentation執行了callActivityOnCreate方法中,會調用Activity的performCreate方法,最終會調用Activity的onCreate方法,這樣應用程序也就啓動了。

應用程序啓動的進程關係圖

應用程序啓動的過程中,主要涉及了Launcher進程、SystemServer進程、Zygote進程和應用程序進程這四個進程,它們之間的關係如下。

騰訊精選面試重點問題:Android源碼分析--應用程序啓動

總結

好了,今天的分享就到這裏,如果你對在面試中遇到的問題,或者剛畢業及工作幾年迷茫不知道該如何準備面試並突破現狀提升自己,對於自己的未來還不夠了解不知道給如何規劃,可以簡信我獲取一下相關面試題及答案資料包及學習視頻。

專注分享大型Bat面試知識,後續會持續更新,希望通過這些高級面試題能夠降低面試Android崗位的門檻,讓更多的Android工程師理解Android系統,掌握Android系統。喜歡的話麻煩點擊一個喜歡在關注一下~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章