BroadCast from http://blog.csdn.net/luoshengyang/article/details/6730748


android啓動

 Step 1. 無論是通過Launcher來啓動Activity,還是通過Activity內部調用startActivity接口來啓動新的Activity,都通過Binder進程間通信進入到ActivityManagerService進程中,並且調用ActivityManagerService.startActivity接口; 

        Step 2. ActivityManagerService調用ActivityStack.startActivityMayWait來做準備要啓動的Activity的相關信息;

        Step 3. ActivityStack通知ApplicationThread要進行Activity啓動調度了,這裏的ApplicationThread代表的是調用ActivityManagerService.startActivity接口的進程,對於通過點擊應用程序圖標的情景來說,這個進程就是Launcher了,而對於通過在Activity內部調用startActivity的情景來說,這個進程就是這個Activity所在的進程了;

        Step 4. ApplicationThread不執行真正的啓動操作,它通過調用ActivityManagerService.activityPaused接口進入到ActivityManagerService進程中,看看是否需要創建新的進程來啓動Activity;

        Step 5. 對於通過點擊應用程序圖標來啓動Activity的情景來說,ActivityManagerService在這一步中,會調用startProcessLocked來創建一個新的進程,而對於通過在Activity內部調用startActivity來啓動新的Activity來說,這一步是不需要執行的,因爲新的Activity就在原來的Activity所在的進程中進行啓動;

        Step 6. ActivityManagerServic調用ApplicationThread.scheduleLaunchActivity接口,通知相應的進程執行啓動Activity的操作;

        Step 7. ApplicationThread把這個啓動Activity的操作轉發給ActivityThread,ActivityThread通過ClassLoader導入相應的Activity類,然後把它啓動起來。

        這樣,Android應用程序的Activity啓動過程就簡要介紹到這裏了,在接下來的兩篇文章中,我們將根據Activity的這兩種啓動情景,深入到應用程序框架層的源代碼裏面去,一步一步地分析它們的啓動過程:



在Android系統中,爲什麼需要廣播機制呢?廣播機制,本質上它就是一種組件間的通信方式,如果是兩個組件位於不同的進程當中,那麼可以用Binder機制來實現,如果兩個組件是在同一個進程中,那麼它們之間可以用來通信的方式就更多了,這樣看來,廣播機制似乎是多餘的。然而,廣播機制卻是不可替代的,它和Binder機制不一樣的地方在於,廣播的發送者和接收者事先是不需要知道對方的存在的,這樣帶來的好處便是,系統的各個組件可以松耦合地組織在一起,這樣系統就具有高度的可擴展性,容易與其它系統進行集成。

它們的實現機理都是消息發佈/訂閱模式的事件驅動模型,消息的生產者發佈事件,而使用者訂閱感興趣的事件



        在第1步中,廣播的接收者把廣播接收器註冊到ActivityManagerService中;在第2步中,廣播的發送者同樣是把廣播發送到ActivityManagerService中,由ActivityManagerService去查找註冊了這個廣播的接收者,然後把廣播分發給它們。

        在第2步的分發的過程,其實就是把這個廣播轉換成一個消息,然後放入到接收器所在的線程消息隊列中去,最後就可以在消息循環中調用接收器的onReceive函數了。這裏有一個要非常注意的地方是,由於ActivityManagerService把這個廣播放進接收器所在的線程消息隊列後,就返回了,它不關心這個消息什麼時候會被處理,因此,對廣播的處理是異步的,即調用sendBroadcast時,這個函數不會等待這個廣播

oadedApk.getReceiverDispatcher在LoadedApk內部創建了一個IIntentReceiver接口,並且傳遞給ActivityManagerService;虛線下面的Step 5到Step 11是發送廣播的過程,在Step 8中,ActivityManagerService利用上面得到的IIntentReceiver遠程接口,調用LoadedApk.performReceiver接口,LoadedApk.performReceiver接口通過ActivityThread.H接口的post函數將這個廣播消息放入到ActivityThread的消息隊列中去,最後這個消息在LoadedApk的Args.run函數中處理,LoadedApk.Args.run函數接着調用MainActivity.BroadcastReceiver的onReceive函數來最終處理這個廣播


能否講一下靜態註冊廣播的過程呢?靜態註冊和動態註冊的過程是一樣的嗎?
回覆gaolixiao:有點區別。靜態註冊的廣播接收者在第一次接收廣播的時候,纔會被啓動起來。這時候如果它所運行在應用程序進程還沒有啓動志來,那麼這個應用程序進程又會首先被啓動起來,以便可以啓動那個靜態註冊的廣播接收者。這個過程會複雜一些。靜態註冊的廣播接收者的啓動過程可以在廣播的發送過程中看到。而動態註冊必須在模塊啓動器來後,註冊了才能接受。
     1. Step 1 - Step 7,計數器服務CounterService通過sendBroadcast把一個廣播通過Binder進程間通信機制發送給ActivityManagerService,ActivityManagerService根據這個廣播的Action類型找到相應的廣播接收器,然後把這個廣播放進自己的消息隊列中去,就完成第一階段對這個廣播的異步分發了;

ActivityManagerService broadcastIntent - >ActivityManagerService.broadcastIntentLocked->if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {  找到匹配的廣播接收器

        2. Step 8 - Step 15,ActivityManagerService在消息循環中處理這個廣播,並通過Binder進程間通信機制把這個廣播分發給註冊的廣播接收分發器ReceiverDispatcher,ReceiverDispatcher把這個廣播放進MainActivity所在的線程的消息隊列中去,就完成第二階段對這個廣播的異步分發了;

        3. Step 16 - Step 17, ReceiverDispatcher的內部類Args在MainActivity所在的線程消息循環中處理這個廣播,最終是將這個廣播分發給所註冊的BroadcastReceiver實例的onReceive函數進行處理。


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