Zygote進程是怎麼啓動的?
首先Init進程是Linux進程啓動後用戶空間的第一個進程,然後去加載inti.rc配置文件,看需要加載哪些服務,Zygote就是其中之一。還有ServiceManager進程。 父進程fork出子進程,如果子進程掛了,那麼父進程會收到子進程發送過來的SIGCHLD信號,進而做處理。
Zygote進程啓動之後做了什麼?
1.Zygote的native層:啓動Android虛擬機,註冊Android的JNI函數,進入Java層。
2.Zygote的Java層:預加載資源(包括主題資源,共享庫等),fork出SystemServer,然後進入loop循環.
Android系統啓動流程?
init.rc裏面需要加載的進程有zygote,servicemanager,surfaceflinger和media等。主要需要了解zygote的啓動流程,如上。還要了解systemserver的啓動流程。下面來看看systemserver啓動流程。
zygote啓動systemserver進程後,在systemserver進程中初始化相關係統服務AMS,PMS,包括啓動bind線程。因爲systemserver裏面的系統服務需要與我們的應用進程通信,而通信就是通過bind機制。還包括調用Java類的入口函數main(),在main()函數裏面加載loop,共享庫,創建上下文等。
系統服務是怎麼啓動的?
把系統服務的bind註冊到serviceManager裏面,通過這種方式發佈系統服務。系統服務跑在什麼線程?bind線程。
systemServer啓動系統服務時怎麼解決相互依賴?
分批啓動,分階段啓動。
如何使用系統服務?
通過getSystemService(name)方法獲取ServiceFetcher,並調用其getService方法。
如何註冊系統服務?
通過調用ServiceManager的addService方法。
什麼時候註冊的系統服務?
SystemServer啓動的時候。系統服務不完全是在SystemServer進程裏面,還有一小部分單獨開闢進程,比如ServiceManager。
系統服務和bind的應用服務有什麼區別?
啓動方式上的區別:系統服務大部分跑在SystemServer進程裏面,也是在SystemServer裏面啓動的,如AMS,WMS,PMS。大部分服務跑在binder線程,少部分服務才跑在自己的工作線程。這裏啓動服務主要是服務初始化工作。而應用服務是客戶端主動請求。
註冊方式上的區別:先看系統服務的註冊,無論是跑在SystemServer進程,還是獨立進程,都要把binder實體對象註冊到ServiceManager,是在啓動的註冊。而應用服務則是客戶端向AMS發起bindService調用,AMS根據該bind對象是否已經註冊進行不同的處理。
使用方式上的區別:系統服務通過上下文的getSystemServer()方法。而應用服務通過bindService發送請求,然後通過回調返回binder。
ServiceManager的啓動:
1.啓動進程:init進程讀取init.rc配置文件,然後開啓ServiceManager進程。
2.啓用binder機制:
3.發佈自己的服務:
4.等待並響應請求:
進程啓動方式:
1.fork,子進程共享父進程資源
2.fork + execve(path,...),子進程資源由path指定。
什麼時候觸發應用進程啓動?
啓動組件時,如果沒有該組件所在的進程沒有啓動,則啓動進程,這是由framework層實現。
如何啓動應用進程,即APP?
AMS通過socket向zygote發消息,zygote收到消息後去啓動應用進程。zygote fork出應用進程後,執行ActivityThread的main函數。應用進程啓動後向AMS報告,註冊ApplicationThread。
如何啓動binder機制?
binder啓動時機,應用進程啓動流程中,zygote啓動應用進程的時候啓動binder機制。
1.打開binder驅動;
2.映射內存,分配緩衝區;
3.註冊binder線程;
4.進入binder loop;
談談你對Application的理解。
Application的作用。
1.保存應用的全局變量。
2.初始化操作。
3.提供應用上下文。應用開啓幾個進程,這裏創建幾個Application對象。
Application的繼承關係。
Application繼承ContextWrapper,ContextWrapper繼承Context。
Application的生命週期。
1.Application構造函數。
2.attachBaseContext,獲取上下文的方法,因此如果在上面Application構造方法裏面使用了上下文就會報錯。
3.onCreate。
談談對Context的理解
Application繼承關係:Application繼承ContextWrapper,ContextWrapper繼承Context。
Application調用順序:先調用Application構造函數,然後調用attachBaseContext,最後調用onCreate。
Activiy的繼承關係:Activity繼承ContextThemeWrapper,ContextThemeWrapper繼承ContextWrapper。
Activiy調用順序:先調用Activiy構造函數,然後調用attachBaseContext,最後調用onCreate。
Service繼承關係:Service繼承ContextWrapper,ContextWrapper繼承Context。
Service調用順序:先調用Service構造函數,然後調用attachBaseContext,最後調用onCreate。
第一個問題:應用裏面有多少個Context?不同的Context之間有什麼區別?
只有Application,Activity和Service有Context,而廣播和ContentProvider沒有。所以,Application,Activity和Service這三者的數量加起來,就是Context的數量。Activity由於需要顯示UI,所以繼承的是ContextThemeWrapper,而Application和Service繼承的是ContextWrapper。
第二個問題:Activity裏面的this和getBaseContext有什麼區別?
this返回的是Context。 getBaseContext返回的是ContextWrapper裏面的mBase。
第三個問題:getApplication和getApplicationContext有什麼區別?
都是返回Application對象,getApplicationContext是Context裏面的抽象方法,而getApplication是Activity和Service特有的,在別的地方不能用,比如廣播不能用。
第四個問題:應用組件的構造函數,attachBaseContext,onCreate的調用順序?
先調用構造函數,然後調用attachBaseContext,最後調用onCreate。
第五個問題:Context的作用。
Context是組件的上下文,便於訪問系統資源,調用系統服務等。
Activity的啓動流程?
創建Activity對象,獲取Application,創建ContextImpl,attach上下文,生命週期回調onCreate()以及其他。
第一個問題:啓動Activity會經歷哪些生命週期回調?
第二個問題:冷啓動大致流程,涉及哪些組件,通信過程是怎樣的?
第三個問題:啓動過程中,生命週期的回調原理?
Activity的顯示原理?
第一個問題:PhoneWindow是什麼,怎麼創建的?
第二個問題:setContentView的原理,DecorView是什麼?
第三個問題:ViewRoot是什麼?有什麼作用?
第四個問題:View的顯示原理是什麼?WMS發揮什麼作用?
應用的UI線程是怎麼啓動的?
第一個問題:什麼是UI線程?
UI線程就是刷新UI所在的線程,而且是單線程。
UI線程==主線程嗎?
對於Activity來說,UI線程就是主線程。
對於View來說,UI線程就是View對應的VIewRootImpl創建時所在的線程。
Activity的DecorView對應VIewRootImpl是在主線程創建的。
因此,如果VIewRootImpl不是在主線程創建,也可以刷新UI。
第二個問題:UI線程的啓動流程,消息循環是怎麼創建的?
第三個問題:瞭解Android的UI顯示原理,UI線程和UI之間是怎麼關聯的?
Service啓動原理
BinderService綁定原理
應用向AMS發起bindService調用,如果binder句柄存在,則AMS直接回調binder句柄,然後應用拿到bindre句柄去調用Service。
如果應用向AMS發起bindService調用時,binder句柄不存在,則AMS先向Service請求binder句柄,Service返回binder句柄給AMS,然後AMS回調binder句柄給應用,應用拿到bindre句柄去調用Service。當然,這個流程的前提是Service已經存在,如果Service不存在,則進入啓動Service流程。
動態廣播的註冊和收發原理
1.註冊廣播封裝了一個binder到AMS;
2.發廣播的時候通過intent找到對應的receiver;
3.普通動態廣播在系統端是並行分發,應用端串行分發;
Content Provider啓動原理
應用A向AMS請求provider的binder對象,如果provider組件沒有啓動,,則先啓動該組件。provider啓動後通過attachApplication向AMS報告自己啓動完畢,AMS收到後向provider發起bindApplication讓provider創建application同時初始化provider。然後provider通過publishContentProvider將binder對象發佈給AMS,AMS收到後將該binder對象返回給應用A。應用A就可以向provider發起CRUD調用。流程圖如下:
屏幕刷新機制
首先View調用requestLayout()方法要重繪,也就是把Runnable放入choreographer的消息隊列,choreographer並沒有馬上去處理該消息,而是向SurfaceFliger請求下一個Vsync信號,當下一個Vsync信號到來時向choreographer發通知,choreographer收到該通知後才處理消息隊列裏的消息。流程如下:
丟幀一般是什麼原因引起的?
主線程有耗時操作,耽誤了 View的繪製。
Android刷新頻率60幀每秒,每隔16ms調用onDraw繪製一次?
刷新頻率是指Vsync發出的頻率,但不一定每次都去繪製。需要應用層主動發起繪製,在下一個Vsync信號來臨時才繪製。
onDraw完後屏幕會立即刷新嗎?
不會,要等下一個Vsync信號。
如果界面沒有重繪,還會每隔16ms刷新屏幕嗎?
會,只是看不出來。界面沒有重繪表示應用層不會收到Vsync信號,但是屏幕還是每隔16ms發出Vsync信號。
如果在屏幕快要刷新的時候纔去繪製會丟幀嗎?
要等下一個Vsync信號。