談?wù)剬ygote的理解
-
Zygote的作用是什么磕仅?
- 啟動SystemServer(從Zygote直接獲取常用類钳垮、JNI函數(shù)焙糟、主題資源、共享庫等)
- 孵化應(yīng)用進(jìn)程(進(jìn)程啟動->準(zhǔn)備工作 ->LOOP)
-
Zygote的啟動流程
-
Zygote進(jìn)程是怎么啟動的晾捏?
- Init進(jìn)程通過init.rc獲取配置然后啟動Zygote進(jìn)程
<u>啟動進(jìn)程的方法:</u>
- <u>fork+handle</u>
- <u>fork+execve</u>
-
啟動后做了什么事
- Zygote的Native世界
- 啟動Android虛擬機
- 注冊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)的啟動流程
- Android有哪些主要的系統(tǒng)進(jìn)程
查看init.rc啟動配置文件:
zygote、servicemanager惦辛、surfaceflinger劳秋、media等
SystemServer不在init.rc中,它是zygote創(chuàng)建的
SystemServer啟動系統(tǒng)服務(wù)
- 這些系統(tǒng)進(jìn)程是怎么啟動的
- 進(jìn)程啟動之后主要做了什么事
- zygote是怎么啟動的
- systemServer是怎么啟動的
- 系統(tǒng)服務(wù)是怎么啟動的裙品?如何解決相互依賴問題?如何發(fā)布這些系統(tǒng)服務(wù)的俗或?桌面如何啟動的市怎?
你知道怎么添加一個系統(tǒng)服務(wù)嗎?
-
如何使用系統(tǒng)服務(wù)辛慰?
context.getSystemService()獲取系統(tǒng)服務(wù)的接口對象
最終是通過SYSTEM_SERVICE_FETCHERS這個hashmap獲取的
-
系統(tǒng)服務(wù)的創(chuàng)建
通過createService()方法從ServiceManager.getService()獲取系統(tǒng)服務(wù)的ibinder對象区匠,然后獲取系統(tǒng)服務(wù)的代理對象,進(jìn)行返回
-
如何注冊系統(tǒng)服務(wù)帅腌?
SystemManager.addService()方法將系統(tǒng)服務(wù)的name和IBinder添加到ServiceManager中
-
什么時候注冊系統(tǒng)服務(wù)驰弄?
SystemServer啟動過程:
- 啟動binder機制
- 啟動各類系統(tǒng)服務(wù)
- 進(jìn)入loop循環(huán)
-
獨立進(jìn)程的系統(tǒng)服務(wù)
進(jìn)程啟動后去獲取IServiceManager,然后調(diào)用addService方法
-
啟動binder機制
- 打開binder驅(qū)動
- 映射內(nèi)存速客,分配緩沖區(qū)
- 啟動binder線程戚篙,進(jìn)入binder loop
1、添加系統(tǒng)服務(wù)的時機
- 在systemServer中溺职,可以加到啟動系統(tǒng)服務(wù)的位置
- 跑在單獨進(jìn)程中岔擂,可以添加到init.rc中
2、服務(wù)要做那些事浪耘?
- 啟動binder機制
- 設(shè)置工作
- 將自己注冊到serviceManager中
3乱灵、應(yīng)用端要做的事?
- 應(yīng)用端使用context.getSystemService()方法獲取系統(tǒng)服務(wù)
系統(tǒng)服務(wù)和bind的應(yīng)用服務(wù)有什么區(qū)別七冲?
- 啟動方法
- 系統(tǒng)服務(wù):在SystemServer中啟動或者自己有獨立進(jìn)程啟動
- 應(yīng)用服務(wù):通過context.startServiceCommon()調(diào)用AMS啟動痛倚,管理service,最終通過應(yīng)用的handleCreateService()啟動service
- 注冊方法
- 系統(tǒng)服務(wù):不論是Java層還是native層都是通過serviceManager的addService方法進(jìn)行注冊
- 應(yīng)用服務(wù):
- 應(yīng)用端發(fā)起bindService調(diào)用
- AMS 向Service端請求binder對象
- Service端發(fā)布binder對象到AMS
- AMS將binder對象通過回調(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對象,最終獲得binder端接口對象掘鄙,進(jìn)行調(diào)用
ServiceManager的啟動和工作原理
-
ServiceManager的啟動
- 啟動進(jìn)程(ServiceManager是一個單獨的進(jìn)程颠区,在init.rc中存在)
- 啟動BInder機制
- 發(fā)布自己的服務(wù)
- 等待并響應(yīng)請求
-
如何獲取ServiceManager
- 獨立線程的Service通過BpBinder(0)獲取ServiceManager的代理對象
-
怎么添加Service?
ServiceManager代理對象的addService會調(diào)用對ServiceManager進(jìn)程發(fā)送一個handle消息通铲,ServiceManager在handle中處理消息毕莱,對service進(jìn)行添加
-
怎么獲取Service?
先獲取ServiceManager代理對象,再調(diào)用getService()方法
應(yīng)用進(jìn)程是怎么啟動的朋截?
-
進(jìn)程啟動方法:
- fork-handle這種方法共享父進(jìn)程資源
- fork-execve
-
應(yīng)用進(jìn)程啟動原理
啟動組件時會監(jiān)測組件的進(jìn)程是否啟動蛹稍,如果沒有則先去啟動進(jìn)程。
應(yīng)用中的IActivityManager時AMS的代理對象部服,AMS中的IAPPlicationThread是應(yīng)用中ApplicationThread的代理對象唆姐,進(jìn)行binder雙向調(diào)用
-
進(jìn)程啟動流程:
- 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方法,對于一般應(yīng)用來說就是執(zhí)行ActivityTThread的main()
- 進(jìn)程啟動后會獲取AMS的代理對象剧蹂,并通過這個代理對象向AMS發(fā)送應(yīng)用進(jìn)程的ApplicationThread對象的代理声功,實現(xiàn)binder雙向調(diào)用。
應(yīng)用是怎么啟動Binder機制的宠叼?
zygote 在fork一個應(yīng)用進(jìn)程后先巴,這個進(jìn)程會先去啟動Binder機制:
- 打開binder驅(qū)動
- 映射內(nèi)存,分配緩沖區(qū)
- 注冊binder線程
- 進(jìn)入binder loop
應(yīng)用天生就支持Binder機制是不是從zygote繼承過來的冒冬?
談?wù)勀銓pplication的理解
- Application有什么作用
- Application的生命周期與應(yīng)用的生命周期相同伸蚯,可以保存應(yīng)用進(jìn)程內(nèi)的全局變量
- 做初始化操作
- 提供應(yīng)用上下文(不會內(nèi)存泄漏)
- Application的生命周期
- 構(gòu)造函數(shù)
- attachBaseContext
- onCreate
- Application怎么初始化?
- 應(yīng)用進(jìn)程的main方法中調(diào)用AMS的代理類進(jìn)行注冊
- 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ù)勀銓ontext的理解
應(yīng)用里面有多少個Context简烤?不同的Context之間有什么區(qū)別剂邮?
Activity里的this和getBaseContext有什么區(qū)別?
getApplication和getApplicationContext有什么區(qū)別横侦?
getApplication是Activity和service中的方法抗斤,getApplicationContext是Context的抽象方法,二者返回的都是application對象丈咐。
應(yīng)用組件的構(gòu)造瑞眼,onCreate、attachBaseContext調(diào)用順序棵逊?
-
Context的作用
作為應(yīng)用組件的上下文伤疙,調(diào)用系統(tǒng)服務(wù)、調(diào)用資源辆影、啟動activity徒像、service等組件
-
Context在哪里創(chuàng)建:
擁有自己的Context的類:
- Application
- Activity
- Service
Application和Service都是繼承自ContextWrapper,ContextWrapper繼承自Context蛙讥,ContextWrapper的實現(xiàn)方法都是锯蛀,內(nèi)部的mBase去完成的,這個mBase就是一個ContextImpl對象次慢,這里使用了靜態(tài)代理的設(shè)計模式旁涤。
Activity繼承自ContextThemeWrapper翔曲,ContextThemeWrapper繼承自ContextWrapper。ContextThemeWrapper比ContextWrapper多了一個mTheme成員變量劈愚。
Activity啟動是調(diào)用performLaunchActivity()方法瞳遍,activity會使用attach方法,這里傳入了一個context對象菌羽。
說說Activity的啟動流程
在應(yīng)用端:
- 創(chuàng)建Activity對象
- 準(zhǔn)備好Application
- 創(chuàng)建ContextImpl
- attach上下文
- 開始什么周期回調(diào)
整體過程:
- 發(fā)送startActivity請求
- AMS查看需要啟動的Activity的進(jìn)程是否啟動
- 如果已經(jīng)啟動則使用scheduleLaunchActivity()方法掠械,通過binder在應(yīng)用端開啟Activity的創(chuàng)建過程
- 如果沒有啟動進(jìn)程,則AMS發(fā)送啟動進(jìn)程請求給Zygote注祖,讓Zygote去fork一個進(jìn)程猾蒂,并執(zhí)行ActivityThread.main()方法
- fork出的進(jìn)程將pid傳給AMS,并且在main中向AMS傳入IApplicationThread進(jìn)行binder的雙向通行是晨。
- AMS中會給這個應(yīng)用進(jìn)程創(chuàng)建Application肚菠,再執(zhí)行第3步
說說Activity的顯示原理
-
在onCreate中調(diào)用
setContentView()
- 創(chuàng)建mDecor(一個FrameLayout布局)
- 將設(shè)置的布局加入mDecor
- 獲取主顯示區(qū)的view(mContentParent)
- 將自定義的布局加載到主顯示區(qū)中
-
主線程在執(zhí)行handleResumeActivity方法中(onResume之后),會對UI進(jìn)行操作:
獲取window對象
獲取decorView對象
獲取windowManager對象
-
將decorView加入windowManager中
創(chuàng)建ViewRootImpl對象
-
ViewRootImpl.setView(mDecor, )
requestLayout()觸發(fā)繪制
-
mWindowSession.addToDisplay(mWindow, )
mWindowSession是應(yīng)用與WMS進(jìn)行通信的對象署鸡,mWindow注冊到WMS后案糙,應(yīng)用與WMS就可以進(jìn)行binder雙向調(diào)用
WMS功能:
- 給應(yīng)用端分配surface
- 掌管surface顯示順序及位置尺寸
- 控制窗口動畫
- 輸入事件分發(fā)
mDecor.setVisibility(View.VISIBLE)限嫌,設(shè)置可見進(jìn)行重繪
- PhoneWindow是什么靴庆?怎么創(chuàng)建的?
- setContentView原理怒医,DecorView是什么炉抒?
- ViewRoot是什么?有什么作用稚叹?
- View的顯示原理是什么焰薄?WMS發(fā)揮什么作用?
應(yīng)用的UI線程是怎么啟動的扒袖?
-
對Activity來說塞茅,UI線程就是主線程
activity.runOnUiThread()
-
對View來說,UI線程就是ViewRootImpl創(chuàng)建的時候所在的線程
View.post(Runnable r)
-
Activity的DecorView對應(yīng)的ViewRootImpl是在主線程創(chuàng)建的
checkThread()
結(jié)論:UI線程就是主線程
UI線程的啟動流程:
- Zygote fork進(jìn)程
- 啟動binder線程
- 執(zhí)行入口函數(shù)(ActivityThread.main())
- 說說UI線程是什么季率?
- UI線程消息循環(huán)是怎么創(chuàng)建的野瘦?
- UI線程和UI體系的關(guān)系