http://blog.csdn.net/caowenbin/article/details/6036726#
ActivityManager在作業系統中有重要的作用,本文利用作業系統源碼,逐步理清ActivityManager的架構,並從靜態類結構圖和動態順序圖表兩個角度分別進行剖析,從而協助開發人員加強對系統架構及進程通訊機制的理解。
ActivityManager的作用
參照SDK的說明,可見ActivityManager的功能是與系統中所有運行著的Activity互動提供了介面,主要的介面圍繞著運行中的進程資訊,任務資訊,服務資訊等。比如函數getRunningServices()的源碼是:
public List<RunningServiceInfo> getRunningServices(int maxNum)
throws SecurityException {
try {
return (List<RunningServiceInfo>)ActivityManagerNative.getDefault()
.getServices(maxNum, 0);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return null;
}
}
從中可以看到,ActivityManager的大多數功能都是調用了ActivityManagerNative類介面來完成的,因此,我們尋跡來看ActivityManagerNative的代碼,並以此揭示ActivityManager的整體架構。
ActivityManager的靜態類圖
通過源嗎,可以發現ActivityManagerNative類的繼承關係如下:
public abstract class ActivityManagerNative extends Binder implements IActivityManager
繼承自Binder類,同時實現了IActivityManager介面。
同樣的,我們繼續沿Binder和IActivityManager上溯,整理出如所示的類結構圖。
在這張圖中,綠色的部分是在SDK中開放給應用程式開發人員的介面,藍色的部分是一個典型的Proxy模式,紅色的部分是底層的服務實現,是真正的動作執行者。這裡的一個核心思想是Proxy模式,我們接下來對此模式加以介紹。
Proxy模式
Proxy模式,也稱代理模式,是經典設計模式中的一種結構型模式,其定義是為其他對象提供一種代理以控制對這個對象的訪問,簡單的說就是在訪問和被訪問對象中間加上的一個間接層,以隔離訪問者和被訪問者的實現細節。
結合上面的類結構圖,其中ActivityManager是一個用戶端,為了隔離它與ActivityManagerService,有效降低甚至消除二者的耦合度,在這中間使用了ActivityManagerProxy代理類,所有對ActivityManagerService的訪問都轉換成對代理類的訪問,這樣ActivityManager就與ActivityManagerService解耦了。這就是代理模式的典型應用情境。
為了讓代理類與被代理類保持一致的介面,從而實現更加靈活的類結構,或者說完美的屏蔽實現細節,通常的作法是讓代理類與被代理類實現一個公用的介面,這樣對調用者來說,無法知道被調用的是代理類還是直接是被代理類,因為二者的介面是相同的。
這個思路在上面的類結構圖裡也有落實,IActivityManager介面類就是起的這個作用。
以上就是代理模式的思路,有時我們也稱代理類為本地代理(Local Proxy),被代理類為遠端代理(Remote Proxy)。
本地代理與遠端代理的Binder
我們再來看一下Binder類的作用,Binder的含義可能譯為粘合劑更為貼切,即將兩側的東西粘貼起來。在作業系統中,Binder的一大作用就是串連本地代理和遠端代理。Binder中最重要的一個函數是:
public final boolean transact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
……
boolean r = onTransact(code, data, reply, flags);
if (reply != null) {
reply.setDataPosition(0);
}
return r;
}
它的作用就在於通過code來表示請求的命令標識,通過data和reply進行資料傳遞,只要遠端代理能實現onTransact()函數,即可做出正確的動作,遠端的執行介面被完全屏蔽了。
當然,Binder的實現還是很複雜的,不僅是類型轉換,還要透過Binder驅動進入KERNEL層來完成進程通訊,這些內容不在本文的範圍之內,故此處不再深入解析相應的機制。此處我們只要知道Binder的transact()函數實現就可以了。
到此為止,我們對ActivityManager的靜態類結構就分析完了,但這還不足以搞清在系統運行中的調用過程,因此,我們以的順序圖表為基礎,結合源碼探索一下ActivityManager運行時的機制。
動態順序圖表
我們以ActivityManager的getRunningServices()函數為例,對上述順序圖表進行解析。
public List<RunningServiceInfo> getRunningServices(int maxNum)
throws SecurityException {
try {
return (List<RunningServiceInfo>)ActivityManagerNative.getDefault()
.getServices(maxNum, 0);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return null;
}
}
可以看到,調用被委託到了ActivatyManagerNative.getDefault()。
static public IActivityManager asInterface(IBinder obj)
{
……
return new ActivityManagerProxy(obj);
}
static public IActivityManager getDefault()
{
……
IBinder b = ServiceManager.getService("activity");
gDefault = asInterface(b);
return gDefault;
}
從上述簡化後的源碼可以看到,getDefault()函數返回的是一個ActivityManagerProxy對象的引用,也就是說,ActivityManager得到了一個本地代理。
因為在IActivityManager介面中已經定義了getServices()函數,所以我們來看這個本地代理對該函數的實現。
public List getServices(int maxNum, int flags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
……
mRemote.transact(GET_SERVICES_TRANSACTION, data, reply, 0);
……
}
從這個代碼版段我們看到,調用遠端代理的transact()函數,而這個mRemote就是ActivityManagerNative的Binder介面。
接下來我們看一下ActivityManagerNative的代碼,因為該類是繼承於Binder類的,所以transact的機制此前我們已經展示了代碼,對於該類而言,重要的是對onTransact()函數的實現。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case GET_SERVICES_TRANSACTION: {
……
List list = getServices(maxNum, fl);
……
return true;
}
……
}
return super.onTransact(code, data, reply, flags);
}
在onTrasact()函數內,雖然代碼特別多,但就是一個switch語句,根據不同的code命令進行不同的處理,比如對於GET_SERVICES_TRANSACTION命令,只是調用了getServices()函數。而該函數的實現是在ActivityManagerService類中,它是ActivityManagerNative的子類,對於該函數的實現細節,不在本文中詳細分析。
Activity啟動
在經過前文的學習以後,我們一起來整理一下Activity的啟動機制。就從Activity的startActivity()函數開始吧。
startActivity()函數調用了startActivityForResult()函數,該函數有源碼如下:
public void startActivityForResult(Intent intent, int requestCode) {
……
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
……
}
可見,功能被委託給Instrumentation對象來執行了。這個類的功能是輔助Activity的監控和測試,在此我們不詳細描述,我們來看它的execStartActivity()函數。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
……
try {
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
在這個函數裡,我們看到了前文熟悉的ActivityManagerNative.getDefault(),沒錯,利用了ActivityManagerService。通過前文的線索,利用Proxy模式,我們可以透過ActivityManagerProxy,通過Binder的transact機制,找到真正的動作執行者,即ActivityManagerService類的startActivity()函數,並沿此線索繼續追蹤源碼,在startActivityLocked()函數裡邊看到了mWindowManager.setAppStartingWindow的語句調用,mWindowManager是WindowManagerService對象,用於負責介面上的具體視窗調試。
通過這樣的源碼追蹤,我們瞭解到了Activity啟動的底層實現機制,也加深了對Proxy模式和Binder機制的理解。從而為學習其他架構打下了基礎。
總結
本文從靜態類結構和動態類結構兩個角度分析了ActivityManager的架構,兼顧了Binder機制和代理模式在處理序間通訊的機理,對協助開發人員深化作業系統的結構和架構具有一定的指導作用。
ActivityManager在作業系統中有重要的作用,本文利用作業系統源碼,逐步理清ActivityManager的架構,並從靜態類結構圖和動態順序圖表兩個角度分別進行剖析,從而協助開發人員加強對系統架構及進程通訊機制的理解。
ActivityManager的作用
參照SDK的說明,可見ActivityManager的功能是與系統中所有運行著的Activity互動提供了介面,主要的介面圍繞著運行中的進程資訊,任務資訊,服務資訊等。比如函數getRunningServices()的源碼是:
public List<RunningServiceInfo> getRunningServices(int maxNum)
throws SecurityException {
try {
return (List<RunningServiceInfo>)ActivityManagerNative.getDefault()
.getServices(maxNum, 0);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return null;
}
}
從中可以看到,ActivityManager的大多數功能都是調用了ActivityManagerNative類介面來完成的,因此,我們尋跡來看ActivityManagerNative的代碼,並以此揭示ActivityManager的整體架構。
ActivityManager的靜態類圖
通過源嗎,可以發現ActivityManagerNative類的繼承關係如下:
public abstract class ActivityManagerNative extends Binder implements IActivityManager
繼承自Binder類,同時實現了IActivityManager介面。
同樣的,我們繼續沿Binder和IActivityManager上溯,整理出如所示的類結構圖。
在這張圖中,綠色的部分是在SDK中開放給應用程式開發人員的介面,藍色的部分是一個典型的Proxy模式,紅色的部分是底層的服務實現,是真正的動作執行者。這裡的一個核心思想是Proxy模式,我們接下來對此模式加以介紹。
Proxy模式
Proxy模式,也稱代理模式,是經典設計模式中的一種結構型模式,其定義是為其他對象提供一種代理以控制對這個對象的訪問,簡單的說就是在訪問和被訪問對象中間加上的一個間接層,以隔離訪問者和被訪問者的實現細節。
結合上面的類結構圖,其中ActivityManager是一個用戶端,為了隔離它與ActivityManagerService,有效降低甚至消除二者的耦合度,在這中間使用了ActivityManagerProxy代理類,所有對ActivityManagerService的訪問都轉換成對代理類的訪問,這樣ActivityManager就與ActivityManagerService解耦了。這就是代理模式的典型應用情境。
為了讓代理類與被代理類保持一致的介面,從而實現更加靈活的類結構,或者說完美的屏蔽實現細節,通常的作法是讓代理類與被代理類實現一個公用的介面,這樣對調用者來說,無法知道被調用的是代理類還是直接是被代理類,因為二者的介面是相同的。
這個思路在上面的類結構圖裡也有落實,IActivityManager介面類就是起的這個作用。
以上就是代理模式的思路,有時我們也稱代理類為本地代理(Local Proxy),被代理類為遠端代理(Remote Proxy)。
本地代理與遠端代理的Binder
我們再來看一下Binder類的作用,Binder的含義可能譯為粘合劑更為貼切,即將兩側的東西粘貼起來。在作業系統中,Binder的一大作用就是串連本地代理和遠端代理。Binder中最重要的一個函數是:
public final boolean transact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
……
boolean r = onTransact(code, data, reply, flags);
if (reply != null) {
reply.setDataPosition(0);
}
return r;
}
它的作用就在於通過code來表示請求的命令標識,通過data和reply進行資料傳遞,只要遠端代理能實現onTransact()函數,即可做出正確的動作,遠端的執行介面被完全屏蔽了。
當然,Binder的實現還是很複雜的,不僅是類型轉換,還要透過Binder驅動進入KERNEL層來完成進程通訊,這些內容不在本文的範圍之內,故此處不再深入解析相應的機制。此處我們只要知道Binder的transact()函數實現就可以了。
到此為止,我們對ActivityManager的靜態類結構就分析完了,但這還不足以搞清在系統運行中的調用過程,因此,我們以的順序圖表為基礎,結合源碼探索一下ActivityManager運行時的機制。
動態順序圖表
我們以ActivityManager的getRunningServices()函數為例,對上述順序圖表進行解析。
public List<RunningServiceInfo> getRunningServices(int maxNum)
throws SecurityException {
try {
return (List<RunningServiceInfo>)ActivityManagerNative.getDefault()
.getServices(maxNum, 0);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return null;
}
}
可以看到,調用被委託到了ActivatyManagerNative.getDefault()。
static public IActivityManager asInterface(IBinder obj)
{
……
return new ActivityManagerProxy(obj);
}
static public IActivityManager getDefault()
{
……
IBinder b = ServiceManager.getService("activity");
gDefault = asInterface(b);
return gDefault;
}
從上述簡化後的源碼可以看到,getDefault()函數返回的是一個ActivityManagerProxy對象的引用,也就是說,ActivityManager得到了一個本地代理。
因為在IActivityManager介面中已經定義了getServices()函數,所以我們來看這個本地代理對該函數的實現。
public List getServices(int maxNum, int flags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
……
mRemote.transact(GET_SERVICES_TRANSACTION, data, reply, 0);
……
}
從這個代碼版段我們看到,調用遠端代理的transact()函數,而這個mRemote就是ActivityManagerNative的Binder介面。
接下來我們看一下ActivityManagerNative的代碼,因為該類是繼承於Binder類的,所以transact的機制此前我們已經展示了代碼,對於該類而言,重要的是對onTransact()函數的實現。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case GET_SERVICES_TRANSACTION: {
……
List list = getServices(maxNum, fl);
……
return true;
}
……
}
return super.onTransact(code, data, reply, flags);
}
在onTrasact()函數內,雖然代碼特別多,但就是一個switch語句,根據不同的code命令進行不同的處理,比如對於GET_SERVICES_TRANSACTION命令,只是調用了getServices()函數。而該函數的實現是在ActivityManagerService類中,它是ActivityManagerNative的子類,對於該函數的實現細節,不在本文中詳細分析。
Activity啟動
在經過前文的學習以後,我們一起來整理一下Activity的啟動機制。就從Activity的startActivity()函數開始吧。
startActivity()函數調用了startActivityForResult()函數,該函數有源碼如下:
public void startActivityForResult(Intent intent, int requestCode) {
……
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
……
}
可見,功能被委託給Instrumentation對象來執行了。這個類的功能是輔助Activity的監控和測試,在此我們不詳細描述,我們來看它的execStartActivity()函數。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
……
try {
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
在這個函數裡,我們看到了前文熟悉的ActivityManagerNative.getDefault(),沒錯,利用了ActivityManagerService。通過前文的線索,利用Proxy模式,我們可以透過ActivityManagerProxy,通過Binder的transact機制,找到真正的動作執行者,即ActivityManagerService類的startActivity()函數,並沿此線索繼續追蹤源碼,在startActivityLocked()函數裡邊看到了mWindowManager.setAppStartingWindow的語句調用,mWindowManager是WindowManagerService對象,用於負責介面上的具體視窗調試。
通過這樣的源碼追蹤,我們瞭解到了Activity啟動的底層實現機制,也加深了對Proxy模式和Binder機制的理解。從而為學習其他架構打下了基礎。
總結
本文從靜態類結構和動態類結構兩個角度分析了ActivityManager的架構,兼顧了Binder機制和代理模式在處理序間通訊的機理,對協助開發人員深化作業系統的結構和架構具有一定的指導作用。