談?wù)剬?duì)Zygote的理解
-
Zygote的作用是什么?
- 啟動(dòng)SystemServer(從Zygote直接獲取常用類、JNI函數(shù)、主題資源、共享庫(kù)等)
- 孵化應(yīng)用進(jìn)程(進(jìn)程啟動(dòng)->準(zhǔn)備工作 ->LOOP)
-
Zygote的啟動(dòng)流程
-
Zygote進(jìn)程是怎么啟動(dòng)的?
- Init進(jìn)程通過init.rc獲取配置然后啟動(dòng)Zygote進(jìn)程
<u>啟動(dòng)進(jìn)程的方法:</u>
- <u>fork+handle</u>
- <u>fork+execve</u>
-
啟動(dòng)后做了什么事
- Zygote的Native世界
- 啟動(dòng)Android虛擬機(jī)
- 注冊(cè)Android的JNI函數(shù)
- 進(jìn)入Java世界
- Zygote的Java世界
- preload resources預(yù)加載資源
- fork 出system server
- loop循環(huán)
- Zygote的Native世界
- Zygote fork要單線程
- Zygote 的IPC沒有采用binder,而是采用socket
-
說說Android系統(tǒng)的啟動(dòng)流程
- Android有哪些主要的系統(tǒng)進(jìn)程
查看init.rc啟動(dòng)配置文件:
zygote、servicemanager、surfaceflinger、media等
SystemServer不在init.rc中,它是zygote創(chuàng)建的
SystemServer啟動(dòng)系統(tǒng)服務(wù)
- 這些系統(tǒng)進(jìn)程是怎么啟動(dòng)的
- 進(jìn)程啟動(dòng)之后主要做了什么事
- zygote是怎么啟動(dòng)的
- systemServer是怎么啟動(dòng)的
- 系統(tǒng)服務(wù)是怎么啟動(dòng)的?如何解決相互依賴問題?如何發(fā)布這些系統(tǒng)服務(wù)的?桌面如何啟動(dòng)的?
你知道怎么添加一個(gè)系統(tǒng)服務(wù)嗎?
-
如何使用系統(tǒng)服務(wù)?
context.getSystemService()獲取系統(tǒng)服務(wù)的接口對(duì)象
最終是通過SYSTEM_SERVICE_FETCHERS這個(gè)hashmap獲取的
-
系統(tǒng)服務(wù)的創(chuàng)建
通過createService()方法從ServiceManager.getService()獲取系統(tǒng)服務(wù)的ibinder對(duì)象,然后獲取系統(tǒng)服務(wù)的代理對(duì)象,進(jìn)行返回
-
如何注冊(cè)系統(tǒng)服務(wù)?
SystemManager.addService()方法將系統(tǒng)服務(wù)的name和IBinder添加到ServiceManager中
-
什么時(shí)候注冊(cè)系統(tǒng)服務(wù)?
SystemServer啟動(dòng)過程:
- 啟動(dòng)binder機(jī)制
- 啟動(dòng)各類系統(tǒng)服務(wù)
- 進(jìn)入loop循環(huán)
-
獨(dú)立進(jìn)程的系統(tǒng)服務(wù)
進(jìn)程啟動(dòng)后去獲取IServiceManager,然后調(diào)用addService方法
-
啟動(dòng)binder機(jī)制
- 打開binder驅(qū)動(dòng)
- 映射內(nèi)存,分配緩沖區(qū)
- 啟動(dòng)binder線程,進(jìn)入binder loop
1、添加系統(tǒng)服務(wù)的時(shí)機(jī)
- 在systemServer中,可以加到啟動(dòng)系統(tǒng)服務(wù)的位置
- 跑在單獨(dú)進(jìn)程中,可以添加到init.rc中
2、服務(wù)要做那些事?
- 啟動(dòng)binder機(jī)制
- 設(shè)置工作
- 將自己注冊(cè)到serviceManager中
3、應(yīng)用端要做的事?
- 應(yīng)用端使用context.getSystemService()方法獲取系統(tǒng)服務(wù)
系統(tǒng)服務(wù)和bind的應(yīng)用服務(wù)有什么區(qū)別?
- 啟動(dòng)方法
- 系統(tǒng)服務(wù):在SystemServer中啟動(dòng)或者自己有獨(dú)立進(jìn)程啟動(dòng)
- 應(yīng)用服務(wù):通過context.startServiceCommon()調(diào)用AMS啟動(dòng),管理service,最終通過應(yīng)用的handleCreateService()啟動(dòng)service
- 注冊(cè)方法
- 系統(tǒng)服務(wù):不論是Java層還是native層都是通過serviceManager的addService方法進(jìn)行注冊(cè)
- 應(yīng)用服務(wù):
- 應(yīng)用端發(fā)起bindService調(diào)用
- AMS 向Service端請(qǐng)求binder對(duì)象
- Service端發(fā)布binder對(duì)象到AMS
- AMS將binder對(duì)象通過回調(diào)給應(yīng)用端
- 應(yīng)用端通過binder調(diào)用service端功能
- 使用方式
- 系統(tǒng)服務(wù):先通過context.getSystemService()獲取服務(wù),然后使用
- 應(yīng)用服務(wù):通過bindService綁定服務(wù),在onServiceConnected的回調(diào)中獲取IBinder對(duì)象,最終獲得binder端接口對(duì)象,進(jìn)行調(diào)用
ServiceManager的啟動(dòng)和工作原理
-
ServiceManager的啟動(dòng)
- 啟動(dòng)進(jìn)程(ServiceManager是一個(gè)單獨(dú)的進(jìn)程,在init.rc中存在)
- 啟動(dòng)BInder機(jī)制
- 發(fā)布自己的服務(wù)
- 等待并響應(yīng)請(qǐng)求
-
如何獲取ServiceManager
- 獨(dú)立線程的Service通過BpBinder(0)獲取ServiceManager的代理對(duì)象
-
怎么添加Service?
ServiceManager代理對(duì)象的addService會(huì)調(diào)用對(duì)ServiceManager進(jìn)程發(fā)送一個(gè)handle消息,ServiceManager在handle中處理消息,對(duì)service進(jìn)行添加
-
怎么獲取Service?
先獲取ServiceManager代理對(duì)象,再調(diào)用getService()方法
應(yīng)用進(jìn)程是怎么啟動(dòng)的?
-
進(jìn)程啟動(dòng)方法:
- fork-handle這種方法共享父進(jìn)程資源
- fork-execve
-
應(yīng)用進(jìn)程啟動(dòng)原理
啟動(dòng)組件時(shí)會(huì)監(jiān)測(cè)組件的進(jìn)程是否啟動(dòng),如果沒有則先去啟動(dòng)進(jìn)程。
應(yīng)用中的IActivityManager時(shí)AMS的代理對(duì)象,AMS中的IAPPlicationThread是應(yīng)用中ApplicationThread的代理對(duì)象,進(jìn)行binder雙向調(diào)用
-
進(jìn)程啟動(dòng)流程:
- AMS調(diào)用startProcessLocked方法打開本地socket,發(fā)送參數(shù)列表給zygote,等待zygotefork出進(jìn)程并把進(jìn)程id傳給AMS
- zygote的loop中調(diào)用runOnce方法fork進(jìn)程,并執(zhí)行進(jìn)程的main方法,對(duì)于一般應(yīng)用來(lái)說就是執(zhí)行ActivityTThread的main()
- 進(jìn)程啟動(dòng)后會(huì)獲取AMS的代理對(duì)象,并通過這個(gè)代理對(duì)象向AMS發(fā)送應(yīng)用進(jìn)程的ApplicationThread對(duì)象的代理,實(shí)現(xiàn)binder雙向調(diào)用。
應(yīng)用是怎么啟動(dòng)Binder機(jī)制的?
zygote 在fork一個(gè)應(yīng)用進(jìn)程后,這個(gè)進(jìn)程會(huì)先去啟動(dòng)Binder機(jī)制:
- 打開binder驅(qū)動(dòng)
- 映射內(nèi)存,分配緩沖區(qū)
- 注冊(cè)binder線程
- 進(jìn)入binder loop
應(yīng)用天生就支持Binder機(jī)制是不是從zygote繼承過來(lái)的?
談?wù)勀銓?duì)Application的理解
- Application有什么作用
- Application的生命周期與應(yīng)用的生命周期相同,可以保存應(yīng)用進(jìn)程內(nèi)的全局變量
- 做初始化操作
- 提供應(yīng)用上下文(不會(huì)內(nèi)存泄漏)
- Application的生命周期
- 構(gòu)造函數(shù)
- attachBaseContext
- onCreate
- Application怎么初始化?
- 應(yīng)用進(jìn)程的main方法中調(diào)用AMS的代理類進(jìn)行注冊(cè)
- AMS通過應(yīng)用的applicationThread調(diào)用bindApplication()方法發(fā)送消息
- 應(yīng)用主線程通過handleBindApplication()進(jìn)程創(chuàng)建Application
- 使用class.newInstance調(diào)用Application的構(gòu)造函數(shù)創(chuàng)建application
- 使用application.attachBaseContext方法設(shè)置上下文contextImpl
- 調(diào)用application.onCreate()方法
談?wù)勀銓?duì)Context的理解
應(yīng)用里面有多少個(gè)Context?不同的Context之間有什么區(qū)別?
Activity里的this和getBaseContext有什么區(qū)別?
getApplication和getApplicationContext有什么區(qū)別?
getApplication是Activity和service中的方法,getApplicationContext是Context的抽象方法,二者返回的都是application對(duì)象。
應(yīng)用組件的構(gòu)造,onCreate、attachBaseContext調(diào)用順序?
-
Context的作用
作為應(yīng)用組件的上下文,調(diào)用系統(tǒng)服務(wù)、調(diào)用資源、啟動(dòng)activity、service等組件
-
Context在哪里創(chuàng)建:
擁有自己的Context的類:
- Application
- Activity
- Service
Application和Service都是繼承自ContextWrapper,ContextWrapper繼承自Context,ContextWrapper的實(shí)現(xiàn)方法都是,內(nèi)部的mBase去完成的,這個(gè)mBase就是一個(gè)ContextImpl對(duì)象,這里使用了靜態(tài)代理的設(shè)計(jì)模式。
Activity繼承自ContextThemeWrapper,ContextThemeWrapper繼承自ContextWrapper。ContextThemeWrapper比ContextWrapper多了一個(gè)mTheme成員變量。
Activity啟動(dòng)是調(diào)用performLaunchActivity()方法,activity會(huì)使用attach方法,這里傳入了一個(gè)context對(duì)象。
說說Activity的啟動(dòng)流程
在應(yīng)用端:
- 創(chuàng)建Activity對(duì)象
- 準(zhǔn)備好Application
- 創(chuàng)建ContextImpl
- attach上下文
- 開始什么周期回調(diào)
整體過程:
- 發(fā)送startActivity請(qǐng)求
- AMS查看需要啟動(dòng)的Activity的進(jìn)程是否啟動(dòng)
- 如果已經(jīng)啟動(dòng)則使用scheduleLaunchActivity()方法,通過binder在應(yīng)用端開啟Activity的創(chuàng)建過程
- 如果沒有啟動(dòng)進(jìn)程,則AMS發(fā)送啟動(dòng)進(jìn)程請(qǐng)求給Zygote,讓Zygote去fork一個(gè)進(jìn)程,并執(zhí)行ActivityThread.main()方法
- fork出的進(jìn)程將pid傳給AMS,并且在main中向AMS傳入IApplicationThread進(jìn)行binder的雙向通行。
- AMS中會(huì)給這個(gè)應(yīng)用進(jìn)程創(chuàng)建Application,再執(zhí)行第3步
說說Activity的顯示原理
-
在onCreate中調(diào)用
setContentView()- 創(chuàng)建mDecor(一個(gè)FrameLayout布局)
- 將設(shè)置的布局加入mDecor
- 獲取主顯示區(qū)的view(mContentParent)
- 將自定義的布局加載到主顯示區(qū)中
-
主線程在執(zhí)行handleResumeActivity方法中(onResume之后),會(huì)對(duì)UI進(jìn)行操作:
獲取window對(duì)象
獲取decorView對(duì)象
獲取windowManager對(duì)象
-
將decorView加入windowManager中
創(chuàng)建ViewRootImpl對(duì)象
-
ViewRootImpl.setView(mDecor, )
requestLayout()觸發(fā)繪制
-
mWindowSession.addToDisplay(mWindow, )
mWindowSession是應(yīng)用與WMS進(jìn)行通信的對(duì)象,mWindow注冊(cè)到WMS后,應(yīng)用與WMS就可以進(jìn)行binder雙向調(diào)用
WMS功能:
- 給應(yīng)用端分配surface
- 掌管surface顯示順序及位置尺寸
- 控制窗口動(dòng)畫
- 輸入事件分發(fā)
mDecor.setVisibility(View.VISIBLE),設(shè)置可見進(jìn)行重繪
- PhoneWindow是什么?怎么創(chuàng)建的?
- setContentView原理,DecorView是什么?
- ViewRoot是什么?有什么作用?
- View的顯示原理是什么?WMS發(fā)揮什么作用?
應(yīng)用的UI線程是怎么啟動(dòng)的?
-
對(duì)Activity來(lái)說,UI線程就是主線程
activity.runOnUiThread() -
對(duì)View來(lái)說,UI線程就是ViewRootImpl創(chuàng)建的時(shí)候所在的線程
View.post(Runnable r) -
Activity的DecorView對(duì)應(yīng)的ViewRootImpl是在主線程創(chuàng)建的
checkThread()
結(jié)論:UI線程就是主線程
UI線程的啟動(dòng)流程:
- Zygote fork進(jìn)程
- 啟動(dòng)binder線程
- 執(zhí)行入口函數(shù)(ActivityThread.main())
- 說說UI線程是什么?
- UI線程消息循環(huán)是怎么創(chuàng)建的?
- UI線程和UI體系的關(guān)系