Android源碼學習——ActivityManager架構解析

來源:互聯網
上載者:User

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機制和代理模式在處理序間通訊的機理,對協助開發人員深化作業系統的結構和架構具有一定的指導作用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.