Android 啟動、繪制、顯示過程
Activity 啟動過程:
startActivity()-> Instrumentation.execStartActivity()-> Binder->ActivityManagerService-> Zygote fork app -> Binder -> ApplicationThread.scheduleLaunchActivity() - > Handler -> ActivityThread.handleLaunchActivity() -> performLauncherActivity -> Instrumentation create Activity -> 設置 application ,創建 ContextImpl,調用 attatch 方法,調用 Instrumentation 的 callActivityOnCreate-> Activity.onCreate()
-> setContentView() -> PhoneWindow.setContentView() -> DecorView . setContentView(); -> handleLaunchActivity()-> handleResumeActivity()-> Instrumentation.callActivityonResume()->Activity.onResume(); -> handleLaunchActivity() -> Activity.makeVisibile() ; -> Activity.makeVisibile()-> WindowManager.addView() - > WindowManagerImpl.addView()->WindowManagerGlobal.addView()-> ViewRootImpl.setView() -> requestLayout -> scheduleTranversals()->Runable->doTranversals()->performTranversales()->measure()->layout()->draw();
涉及到進程間通訊 Binder
涉及到線程間通訊 Handler
涉及到 View 的繪制流程
關鍵類還有 Window, PhoneWindow ,WindowManager ,WindowManagerImpl, WindowManagerGlobal, ViewRootImpl, DecorView
啟動過程
- 不論是通過從桌面上點擊還是通過 startActivity 都會調用到 startActivitForResult 方法,然後會調用 Instrumentation 的方法, Instrumentation 是應用和系統服務的一個橋梁),Instrumentation 的方法會通過 Binder 方式調用 ActivityManagerService 的 startActivity 方法。同時會把 ApplicationThread 這個 Binder 傳入給 ActivityManangerService 。這樣 ActivityManangerService 就可以通過 ApplicaitonThread 與 ActivityThread 進行通訊了。
- ActivityManagerService 收到了 startActivity ,會向 zygote 進程發送創建進程的請求
- Zygote 創建子進程成功,即 app 進程
- 然後經過一系列的準備,會通過 Binder 方式調用 ApplicationThread , 通過 Handler 調用 ActivityThread 的 handleLaunchActivity 。在 handleLaunchActivity 中調用 performLaunchActivity 這個方法,在這個方法中會通過 Instumention 使用 classloader 創建 Activity 對象,然後初始化 application ,ContextImpl ,設置主題,調用 attatch 方法,然後通過調用 Instrumentation 來調用 activity 的生命周期方法 onCreate()。 在 ActivityThread 的 handleLaunchActivity 的方法中,在調用 performLaunchActivity以後 會繼續調用 handleResumeActivity 方法,該方法會通過 Instrumentation 調用 activity 的生命周期方法 onResume().
顯示過程
- 在啟動過程中,通過 ActivityThread 的 handlerLauncherActivity 方法,會調用到 activity 的生命周期方法 onCreate()。在 onCreate() 中調用 setContentView() 方法,設置布局文件,該方法會調用 getWindow.setContentView() 方法, getWindow() 拿到的是 window 對象,Window 的實現類是 PhoneWindow ,所以調用的是 PhoneWindow 的 setContentView() 方法,在 PhoneWindow 的 setContentView() 中會調用 installDecorView() 方法來創建 DecorView ,然後通過 layoutinflate 的 inflate 方法把布局文件加載到 DecorView 的 ContentView 中,雖然已經把布局添加到了 Decorview ,但是還沒有顯示出來。
- 在啟動過程中,handlerLauncherActivity() 方法中,在調用 performLauncherActivity 方法以後,會調用 handleResumeActivity 方法,該方法會調用 activity 的 makeVisible() 方法,使 DecorView 通過 WindowManager 加載到屏幕上顯示。那布局怎麽繪制出來的呢,看下面。
繪制過程
- 在 調用 activity 的 makeVisible() 方法後,把 DecorView 通過 addView 方法添加到了 WindowManager 中,WindowManager 的實現類是 WindowManagerImpl ,WindowManagerImpl 的 addView 方法調用了 WindowManagerGlobal 的 addView 方法,在 WindowManagerGlobal 的 addView 方法中,初始化了 ViewRootImpl 類,並通過 setView 方法把 View 和參數註入,然後調用了 requestLayout 方法, requestLayout 會調用 scheduleTraversal 然後調用一系列方法以後,會調用 measure ,layout ,draw 方法,完成布局的測量,布局和繪畫。以上就完成了布局的繪制,這時手機上就顯示出來了設置的布局。
ViewGroup-------------------------------> View
performMeasure -> measuer -> onMeasure -> measure
performLayout -> layout -> onLayout -> layout
performDraw -> draw -> onDraw -> draw
關鍵類:
- Instrumentation: 應用程序與系統服務的橋梁。為什麽是橋梁呢,首先是 startActivity ,會通過 Instrumentation 的 execStartActivity 方法調用 ActivityManagerService 的方法。然後在 acitivty 的生命周期方法的調用,都是由 Instrumentation 調用的。
Android 啟動、繪制、顯示過程