AMS那些事兒

這里說的AMS進程窑睁,實際指的是System_server進程,System_server進程起來的時候啟動AMS服務(wù)夫植,AMS實際是ActivityManagerService的縮寫微饥。

ActivityManagerService

管理Activity的生命周期

ActivityManagerNative

ActivityManagerService在服務(wù)器端的實現(xiàn),客戶端的請求調(diào)用ActivityManagerProxy后寥院,通過IBinder,最終會在ActivityManagerNative中實現(xiàn)涛目。ActivityManagerNative再通過調(diào)用ActivityManagerService的相關(guān)功能秸谢,以完成客戶端請求凛澎。

ActivityManagerProxy

ActivityManagerService的在客戶端的代理。負(fù)責(zé)和服務(wù)器端的ActivityManagerNative通訊估蹄。

點擊應(yīng)用目錄中應(yīng)用icon的啟動流程

(1)LauncherActivity通過Binder進程間通信的方式將應(yīng)用的信息通過Intent的方式傳遞給AMS塑煎,由AMS進行調(diào)度。
(2)如果系統(tǒng)中不存在該進程時元媚,AMS將會請求Zygote服務(wù)去fork一個子進程轧叽,成功后返回一個pid給AMS,并由AndroidRuntime機制調(diào)起ActivityThread中的main()方法刊棕。
(3)緊接著炭晒,應(yīng)用程序的Main Looper被創(chuàng)建,ActivityThread被實例化成為對象并將Application的信息以進程間通信的方式再次回饋給AMS甥角。此處指的是AMS會獲得一個binder對象网严,即ApplicationThread。AMS就是通過這個binder對象來調(diào)用應(yīng)用程序中的方法嗤无。同樣的應(yīng)用程序也通過AMS客戶端的代理類震束,ApplicationProxy來調(diào)用AMS的方法。
(4)AMS接收到客戶端發(fā)來的請求數(shù)據(jù)之后当犯,首先將應(yīng)用程序綁定垢村,并啟動應(yīng)用程序的Activity,開始執(zhí)行Activity的生命周期嚎卫。

ActivityThread

1915184-b76be1a1e19381df.png

從圖中可以知道嘉栓,mActivitiesmServicesmProviderMap 這三個變量都被保存在ArrayMap之中拓诸,他們分別保存了應(yīng)用中所有的Activity對象侵佃、Services對象、和ContentProvider對象奠支。 咦馋辈?同為四大組件的BroadcastReceive去哪里了?注意倍谜,BroadcastReceiver對象沒有必要用任何數(shù)據(jù)結(jié)構(gòu)來保存迈螟,因為BroadcastReceiver對象的生命周期很短暫,屬于我調(diào)用它時尔崔,再創(chuàng)建運行井联,因此不需要保存BroadcastReceiver的對象。
我們都知道應(yīng)用中Applicaiton對象是唯一的您旁,而mInitialApplication變量是恰恰是Application對象。當(dāng)你的應(yīng)用自定義一個派生Applicaiton類轴捎,則它就是mInitialApplication了鹤盒。
ApplicationThread類型變量mAppThread是一個Binder實體對象蚕脏,ActivityManagerService作為Client端調(diào)用ApplicationThread的接口,目的是用來調(diào)度管理Activity侦锯。
變量mResourcesManager管理著應(yīng)用中的資源驼鞭。
ActivityThread相當(dāng)于一個CEO,管理調(diào)度著幾乎所有的Android應(yīng)用進程的資源和四大組件

ActivityThread的main函數(shù)

public static void More ...main(String[] args) {
5220 SamplingProfilerIntegration.start();
5221
5222 // CloseGuard defaults to true and can be quite spammy. We
5223 // disable it here, but selectively enable it later (via
5224 // StrictMode) on debug builds, but using DropBox, not logs.
5225 CloseGuard.setEnabled(false);

5226 // 初始化應(yīng)用中需要使用的系統(tǒng)路徑
5227 Environment.initForCurrentUser();
5228
5229 // Set the reporter for event logging in libcore
5230 EventLogger.setReporter(new EventLoggingReporter());
5231 //增加一個保存key的provider
5232 Security.addProvider(new AndroidKeyStoreProvider());
5233
5234 // Make sure TrustedCertificateStore looks in the right place for CA certificates //為應(yīng)用設(shè)置當(dāng)前用戶的CA證書保存的位置
5235 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
5236 TrustedCertificateStore.setDefaultUserDirectory(configDir);
5237 //設(shè)置進程的名稱5238 Process.setArgV0("<pre-initialized>");
5239
5240 Looper.prepareMainLooper();
5241 //創(chuàng)建ActivityThread 對象
5242 ActivityThread thread = new ActivityThread();
5243 thread.attach(false);
5244
5245 if (sMainThreadHandler == null) {
5246 sMainThreadHandler = thread.getHandler();
5247 }
5248
5249 if (false) {
5250 Looper.myLooper().setMessageLogging(new
5251 LogPrinter(Log.DEBUG, "ActivityThread"));
5252 }
5253
5254 Looper.loop();
5255
5256 throw new RuntimeException("Main thread loop unexpectedly exited");
5257 }

下面的這段程序尺碰,首先Looper.prepareMainLooper();是為主線程創(chuàng)建了Looper挣棕,然后thread.getHandler();是保存了主線程的Handler,最后Looper.loop();進入消息循環(huán)亲桥。

Looper.prepareMainLooper(); //創(chuàng)建ActivityThread 對象 
ActivityThread thread = new ActivityThread(); 
thread.attach(false);
 if (sMainThreadHandler == null) 
{ 
        sMainThreadHandler =thread.getHandler(); 
}
 if (false) 
{
       Looper.myLooper().setMessageLogging(new      LogPrinter(Log.DEBUG,"ActivityThread")); 
} 
Looper.loop(); 
throw new RuntimeException("Main thread loop unexpectedly exited"); }

下面好好研究這段代碼

ActivityThread thread = new ActivityThread();
thread.attach(false);

進入attach方法

private void attach(boolean system)
 { 
    sCurrentActivityThread = this; 
    mSystemThread = system;
     if (!system) 
      { ...// 以上省略 
            RuntimeInit.setApplicationObject(mAppThread.asBinder()); 
            final IActivityManager mgr = ActivityManagerNative.getDefault(); 
            try 
           { 
                   mgr.attachApplication(mAppThread); 
            } 
           catch (RemoteException ex) 
           { 
                 throw ex.rethrowFromSystemServer(); 
           } ...// 以下省略 
   }
}

mAppThread的初始化

final ApplicationThread mAppThread = new ApplicationThread();

mAppThread是ActivityThread的成員變量洛心。調(diào)用ActivityManagerService的attachApplication()方法,將mAppThread 作為參數(shù)傳入ActivityManagerService题篷,這樣ActivityManagerService就可以調(diào)用ApplicaitonThread的接口了词身。ActivityManagerService作為Client端調(diào)用ApplicaitonThread的接口管理Activity。

在應(yīng)用中通過intent啟動Activity的過程

首先調(diào)用startActivity番枚,最后都會轉(zhuǎn)到startActivityForResult法严。然后調(diào)用Instrumentation.execStartActivity,在execStartActivity里會調(diào)用ActivityManagerNative.getDefault().startActivity葫笼。ActivityManagerNative.getDefault()就是ActivityManagerProxy深啤,這個是AMS在客戶端進程使用的代理類,在ActivityManagerNative.getDefault()中會通過ServiceManager.getService("activity")獲取ActivityManagerService 提供的 Binder 接口路星,并將這個binder傳入ActivityManagerProxy溯街。這樣ActivityManagerProxy調(diào)用starActivity,里面就會調(diào)用了AMS的相應(yīng)函數(shù)奥额。這樣就完成了從Activity到AMS的一次調(diào)用苫幢。那么如果AMS想要調(diào)用Activity的方法呢。這時候就用到剛才說的出入AMS的

參考資料:

Framework源碼分析(一):ActivityManagerService
http://www.reibang.com/p/194a37755fea
Framework源碼分析(三):ActivityThread
http://www.reibang.com/p/b6ac0c2fa240
ActivityThread的main方法究竟做了什么垫挨?
http://www.reibang.com/p/0efc71f349c8
Android Activity生命周期是如何實現(xiàn)的
http://www.reibang.com/p/27d06a6b7007
框架層理解Activity生命周期(APP啟動過程)
http://www.cnblogs.com/feng9exe/p/5706890.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末韩肝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子九榔,更是在濱河造成了極大的恐慌哀峻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哲泊,死亡現(xiàn)場離奇詭異剩蟀,居然都是意外死亡,警方通過查閱死者的電腦和手機切威,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門育特,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事缰冤∪В” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵棉浸,是天一觀的道長怀薛。 經(jīng)常有香客問我,道長迷郑,這世上最難降的妖魔是什么枝恋? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮嗡害,結(jié)果婚禮上焚碌,老公的妹妹穿的比我還像新娘。我一直安慰自己就漾,他們只是感情好呐能,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抑堡,像睡著了一般摆出。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上首妖,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天偎漫,我揣著相機與錄音,去河邊找鬼有缆。 笑死象踊,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棚壁。 我是一名探鬼主播杯矩,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼袖外!你這毒婦竟也來了史隆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤曼验,失蹤者是張志新(化名)和其女友劉穎泌射,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鬓照,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡熔酷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了豺裆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拒秘。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翼抠,到底是詐尸還是另有隱情咙轩,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布阴颖,位于F島的核電站,受9級特大地震影響丐膝,放射性物質(zhì)發(fā)生泄漏量愧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一帅矗、第九天 我趴在偏房一處隱蔽的房頂上張望偎肃。 院中可真熱鬧,春花似錦浑此、人聲如沸累颂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽紊馏。三九已至,卻和暖如春蒲犬,著一層夾襖步出監(jiān)牢的瞬間朱监,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工原叮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赫编,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓奋隶,卻偏偏與公主長得像擂送,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唯欣,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容