轉(zhuǎn)載請(qǐng)注明文章出處LooperJing辛友!
之前寫過Service的啟動(dòng)過程办陷,相對(duì)來說Activity的啟動(dòng)過程比Service的啟動(dòng)過程更為復(fù)雜膨报,其一Activity的生命周期方法比Service多瞳步,其二Activity具有啟動(dòng)模式和返回棧抠璃。寫本文的目的在于更清晰的梳理Activity的啟動(dòng)過程术奖,加強(qiáng)自己的內(nèi)功修煉礁遵,博客粉絲日益增多,力在以最簡(jiǎn)單的方式讓大家理解采记,跟大家一起學(xué)習(xí)佣耐。
Activity的啟動(dòng)過程計(jì)劃用三篇博客來寫淹接;
- 第一篇(本文)背稼,側(cè)重Binder視角或者從進(jìn)程這方面,對(duì)Activity啟動(dòng)先從整體有個(gè)把握磅氨,代碼少既棺,理論多讽挟。
- 第二篇,深入源碼丸冕,分析Launcher進(jìn)程向SystemServer進(jìn)程發(fā)起startActivity請(qǐng)求,SystemServer進(jìn)程在向zygote進(jìn)程發(fā)起請(qǐng)求耽梅,最后孵化出應(yīng)用進(jìn)程的這一過程。
- 第三篇:深入源碼胖烛,由Zygote進(jìn)程孵化的應(yīng)用進(jìn)程是如何啟動(dòng)Activity的眼姐。
一、Binder的基本理解
Activity的啟動(dòng)有多次IPC過程佩番,所以Binder屬于預(yù)備知識(shí)众旗,幫助我們更好理解系統(tǒng)的C/S的這種架構(gòu)模式,我看過幾篇文章還不錯(cuò)趟畏,推薦給大家逝钥。
簡(jiǎn)單說Binder(1)
作者寫的很清晰,相信看過之后拱镐,在JAVA的層面上艘款,立馬明白Binder的IPC過程是怎么回事。可能是講解Binder機(jī)制最好的文章
加強(qiáng)理解一下Android Bander設(shè)計(jì)與實(shí)現(xiàn) - 設(shè)計(jì)篇
最經(jīng)典的不多說了沃琅,值得反復(fù)看Android源碼解析RPC系列(一)---Binder原理
這一篇是我去年寫的哗咆,都不好意思一塊貼出來了。
二益眉、Activity啟動(dòng)的雙向IPC過程
一般Android各個(gè)應(yīng)用進(jìn)程的啟動(dòng)都以這樣一條路線晌柬,init進(jìn)程 –> Zygote進(jìn)程 –> SystemServer進(jìn)程 –>各種應(yīng)用進(jìn)程
- Init進(jìn)程:Linux的根進(jìn)程姥份,Android系統(tǒng)是基于Linux系統(tǒng)的,因此可以算作是整個(gè)android操作系統(tǒng)的第一個(gè)進(jìn)程年碘;
- Zygote進(jìn)程是所有應(yīng)用進(jìn)程的父進(jìn)程澈歉,所有的應(yīng)用進(jìn)程都是它孵化出來的;
- SystemServer進(jìn)程含有一些核心的服務(wù)屿衅,比如ActivityManagerService埃难,PackageManagerService,WindowManagerService等涤久;
- 各種應(yīng)用進(jìn)程:?jiǎn)?dòng)自己編寫的客戶端應(yīng)用時(shí)涡尘,有自己的虛擬機(jī)與運(yùn)行環(huán)境。
由此可知應(yīng)用的第一個(gè)Activity的啟動(dòng)是多個(gè)進(jìn)程相互配合的結(jié)果响迂,多個(gè)進(jìn)程相互配合就少不了使用Binder進(jìn)行IPC了考抄,現(xiàn)在看一次IPC調(diào)用的過程是怎樣的。
上圖大概說明了一次IPC的過程蔗彤,或許你現(xiàn)在對(duì)里面各個(gè)類還不是很清楚川梅,沒關(guān)系,大致了解一下
ActivityManagerService(下文簡(jiǎn)稱AMS)然遏,AMS是Android中最核心的服務(wù)挑势,實(shí)現(xiàn)了ActivityManager,主要負(fù)責(zé)系統(tǒng)中四大組件的啟動(dòng)啦鸣、切換潮饱、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度等工作,AMS提供了一個(gè)ArrayList mHistory來管理所有的Activity诫给,Activity在AMS中的形式是ActivityRecord香拉,Task在AMS中的形式為TaskRecord,進(jìn)程在AMS中的管理形式為ProcessRecord中狂,它在Android中特別重要凫碌。
ActivityManagerNative(下文簡(jiǎn)稱AMN):由于AMS是系統(tǒng)核心服務(wù)在SystemServer進(jìn)程里面,很多API不能直接開放供客戶端使用胃榕,所以需要通過IPC的方式盛险,具體是這樣的,ActivityManager類內(nèi)部調(diào)用AMN的getDefault函數(shù)得到一個(gè)ActivityManagerProxy對(duì)象勋又,通過它可與AMS通信苦掘。
ActivityManagerProxy(下文簡(jiǎn)稱AMP):AMP是AMS在客戶端進(jìn)程的一個(gè)代理,通過AMP里面的方法請(qǐng)求AMS楔壤。
Instrumentation:Instrumentaion是一個(gè)工具類鹤啡,一個(gè)大管家。當(dāng)它被啟用時(shí)蹲嚣,系統(tǒng)先創(chuàng)建它递瑰,再通過它來創(chuàng)建其他組件祟牲。另外,系統(tǒng)和組件之間的交互也將通過Instrumentation來傳遞抖部,這樣说贝,Instrumentation就能監(jiān)測(cè)系統(tǒng)和這些組件的交互情況了。在實(shí)際使用中慎颗,我們可以創(chuàng)建Instrumentation的派生類來進(jìn)行相應(yīng)的處理乡恕。Android中Junit的使用到了Intrstrumentation。關(guān)于它更詳細(xì)的了解哗总,戳我几颜。
OK倍试,現(xiàn)在我們知道讯屈,Activity是如何向AMS發(fā)出startActivity這個(gè)請(qǐng)求了,這意味著Activity可以與AMS進(jìn)行通信县习,但是AMS卻不能與Activity通信涮母,Binder是單向的,所以在Activity發(fā)出請(qǐng)求之后躁愿,AMS需要通知Activity發(fā)生狀態(tài)改變叛本,要做到這一點(diǎn),自然就在AMS到Activity這個(gè)過程建立一個(gè)Binder彤钟,如下来候。
大致過程就是,SystemServer進(jìn)程在收到請(qǐng)求后逸雹,再通過IPC向應(yīng)用進(jìn)程發(fā)送scheduleLaunchActivity請(qǐng)求营搅,應(yīng)用進(jìn)程的binder線程(ApplicationThread)在收到請(qǐng)求后,通過handler向主線程發(fā)送LAUNCH_ACTIVITY消息梆砸,主線程在收到Message后转质,創(chuàng)建目標(biāo)Activity,并回調(diào)Activity.onCreate()等方法帖世。
對(duì)上面的理解不是太明白休蟹,在看下面這張圖,簡(jiǎn)單多了日矫,AMS到Activity這個(gè)過程建立了一個(gè)Binder赂弓,Activity到AMS這個(gè)過程也建立了一個(gè)Binder,這就能相互通信了哪轿。
上圖就是Activity與AMS之間的雙向Binder連接拣展,(備注:這個(gè)就是理解Activity啟動(dòng)流程的指南針,不記住這個(gè)缔逛,復(fù)雜的啟動(dòng)流程會(huì)讓你暈頭轉(zhuǎn)向)备埃。Activity用IActivityManager提供的API向AMS提出執(zhí)行某個(gè)動(dòng)作的請(qǐng)求(本例中是啟動(dòng)RemoteService)姓惑,AMS通過IApplicationThread提供的API來控制Activity所在的應(yīng)用程序,這些API包括schedulePauseActivity()按脚、scheduleStopActivity()等于毙。
IActivityManager接口定義的API,啟動(dòng)四大組件的等多種請(qǐng)求都在里面辅搬。
IApplicationThread接口定義的API唯沮,一看就比IActivityManager高逼格一點(diǎn),IActivityManager好多方法是start開頭堪遂,表示去AMS請(qǐng)求介蛉,IApplicationThread以schedule開頭,表示對(duì)Activity進(jìn)行調(diào)度溶褪。
分析到這里币旧,我們不知不覺間忽略了兩個(gè)問題,那就是啟動(dòng)Activity至少需要兩個(gè)前提猿妈,第一是吹菱,應(yīng)用進(jìn)程存在,第二AMS已經(jīng)初始化完畢彭则。在調(diào)用startActivity方法時(shí)候鳍刷,如果我們的應(yīng)用進(jìn)程不存在,Activity能啟動(dòng)嗎俯抖,當(dāng)然是不能的输瓜,比如點(diǎn)擊桌面圖標(biāo)的時(shí)候,這個(gè)時(shí)候需要先創(chuàng)建進(jìn)程芬萍。關(guān)于Zygote孵化應(yīng)用進(jìn)程尤揣,這個(gè)暫時(shí)不說,先看看AMS服務(wù)注冊(cè)担忧。
三芹缔、AMS服務(wù)注冊(cè)
先忽略 Activity調(diào)用ActivityManagerService啟動(dòng)應(yīng)用,直接從SystemServer的main方法說起瓶盛。
SystemServer.java
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
run方法中最欠,調(diào)用了startBootstrapServices。
private void startBootstrapServices() {
......
//啟動(dòng)AMS服務(wù)
Installer installer = mSystemServiceManager.startService(Installer.class);
//請(qǐng)注意這里參數(shù)是Lifecycle惩猫,因?yàn)锳MS是在Lifecycle里面new出來的
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
mActivityManagerService.initPowerManagement();
......
mActivityManagerService.setSystemProcess();
......
}
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
try {
serviceClass = (Class<SystemService>)Class.forName(className);
} catch (ClassNotFoundException ex) {
Slog.i(TAG, "Starting " + className);
}
return startService(serviceClass);
}
繼續(xù)
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
// 1芝硬、創(chuàng)建服務(wù)
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
// 如果傳進(jìn)來的是ActivityManagerService.Lifecycle對(duì)象,那么ActivityManagerService就能被創(chuàng)建
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
}
// 2轧房、注冊(cè)服務(wù)
mServices.add(service);
// 3拌阴、啟動(dòng)服務(wù)
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name
+ ": onStart threw an exception", ex);
}
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
ActivityManagerService.java
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
//ActivityManagerService被new出來了
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
// 啟動(dòng)
mService.start();
}
public ActivityManagerService getService() {
return mService;
}
}
private void start() {
Process.removeAllProcessGroups();
mProcessCpuThread.start();
mBatteryStatsService.publish(mContext);
mAppOpsService.publish(mContext);
Slog.d("AppOps", "AppOpsService published");
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
回到 startBootstrapServices里面調(diào)用的 mActivityManagerService.setSystemProcess();
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
......
// 設(shè)置application info LoadedApkinfo 有關(guān) framework-res.apk
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
//給SystemServer進(jìn)程創(chuàng)建ProcessRecord,adj值奶镶,就是將SystemServer進(jìn)程加入到AMS進(jìn)程管理機(jī)制中迟赃,跟應(yīng)用進(jìn)程一致
synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
ServiceManager這里面注冊(cè)了很多的服務(wù)陪拘,可通過dumpsys <服務(wù)名>命令查看。比如查看CPU信息命令dumpsys cpuinfo纤壁,查看graphics信息命令dumpsys gfxinfo左刽。在Android中所有的核心服務(wù),并不是直接給上層使用酌媒,都先交給ServiceManager管理欠痴,上層使用的時(shí)候可以從ServiceManager獲取,ServiceManager相當(dāng)于一個(gè)路由作用∶胱桑現(xiàn)在來看一張經(jīng)典的圖喇辽。其中注冊(cè)服務(wù),獲取服務(wù)以及使用服務(wù)雨席,每一次都是一個(gè)完整的Binder IPC過程菩咨,可見理解Binder是多么的重要啊。關(guān)于AMS啟動(dòng)得深入了解舅世,請(qǐng)戳我旦委。
- 注冊(cè)服務(wù):首先AMS注冊(cè)到ServiceManager奇徒。AMS所在進(jìn)程(SystemServer)是客戶端雏亚,ServiceManager是服務(wù)端。
- 獲取服務(wù):Client進(jìn)程使用AMS前摩钙,須先向ServiceManager中獲取AMS的代理類AMP罢低。該過程。AMP所在進(jìn)程(應(yīng)用進(jìn)程)是客戶端胖笛,ServiceManager是服務(wù)端网持。
- 使用服務(wù): app進(jìn)程根據(jù)得到的代理類AMP,便可以直接與AMS所在進(jìn)程交互。該過程长踊,AMP所在進(jìn)程(應(yīng)用進(jìn)程)是客戶端功舀,AMS所在進(jìn)程(SystemServer)是服務(wù)端。
OK 身弊,本文終于寫完了辟汰,翻看源碼,查閱資料阱佛,畫圖花了兩天時(shí)間帖汞,最后回顧一下,本文解釋了雙向Binder是如何建立的凑术?這個(gè)是最重要的部分翩蘸,其次AMS作為管理Android系統(tǒng)組件的核心服務(wù),AMS是如何注冊(cè)的淮逊?(在SystemServer執(zhí)行run()方法的時(shí)候被創(chuàng)建催首,并運(yùn)行在獨(dú)立的進(jìn)程中)扶踊。OK,see you郎任。
·
Please accept mybest wishes for your happiness and success
參考鏈接:
http://www.cloudchou.com/android/post-788.html
[Android源碼解析之(八)-->Zygote進(jìn)程啟動(dòng)流程]
(http://blog.csdn.net/qq_23547831/article/details/51104873)
[深入理解Android卷二 全文-第六章]深入理解ActivityManagerService