Framework基礎(chǔ):應(yīng)用是如何跟系統(tǒng)服務(wù)打交道的

Android有許多系統(tǒng)服務(wù),例如ActivityManagerService,PowerManagerService等,這些系統(tǒng)服務(wù)都跑在SystemServer進(jìn)程之中。而普通的應(yīng)用跑在自己的進(jìn)程里面。那普通應(yīng)用要怎樣才能使用到系統(tǒng)服務(wù)呢?這個(gè)就相當(dāng)于普通應(yīng)用進(jìn)程跟SystemServer進(jìn)程進(jìn)行通行,不同進(jìn)程進(jìn)行通信,就是跨進(jìn)程的通信啦。Android中特有的跨進(jìn)程通信的方式是binder通信。下面說下應(yīng)用與系統(tǒng)ActivityManagerService交互的過程。

應(yīng)用是如何獲取到ActivityManager的呢?###

下圖是獲取ActivityManager的內(nèi)部時(shí)序圖

獲取ActivityManager內(nèi)部時(shí)序圖.png

應(yīng)用層調(diào)用Context的getSystemService方法獲取到ActivityManager

ActivityManager mActivityManager;
mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);  

下面調(diào)用到ContextImpl的getSystemService

    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name);
    }

進(jìn)入SystemServiceRegistry.getSystemService(this, name)方法,可以看到首先通過SYSTEM_SERVICE_FETCHERS的get方法返回一個(gè)ServiceFetcher,然后通過ServiceFetcher的getService方法返回一個(gè)ActivityManager。

   public static Object getSystemService(ContextImpl ctx, String name) {
       ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
       return fetcher != null ? fetcher.getService(ctx) : null;
   }

SYSTEM_SERVICE_FETCHERS是一個(gè)HashMap,key是服務(wù)名稱,內(nèi)容是ServiceFetcher對象。

    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();

SYSTEM_SERVICE_FETCHERS是保存著所有ServiceFetcher的全局變量,我們看看這個(gè)全局變量是怎么填充的。通過靜態(tài)塊中的registerService方法填充。

        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() {
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});

看看這個(gè)registerService函數(shù),可以看到SYSTEM_SERVICE_FETCHERS通過put把系統(tǒng)服務(wù)填充到自己里面。

    private static <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }

ServiceFetcher是一個(gè)接口,他的實(shí)現(xiàn)是CachedServiceFetcher。

    static abstract interface ServiceFetcher<T> {
        T getService(ContextImpl ctx);
    }

就是說一個(gè)CachedServiceFetcher是跟一個(gè)系統(tǒng)服務(wù)相關(guān)聯(lián)的,其通過createService創(chuàng)建關(guān)聯(lián)的系統(tǒng)服務(wù),通過getService獲取關(guān)聯(lián)的系統(tǒng)服務(wù)??碿reateService方法,可以看到new了一個(gè)ActivityManager對象,所以返回的就是一個(gè)ActivityManager對象啦。

        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() {
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});
系統(tǒng)服務(wù)數(shù)據(jù)結(jié)構(gòu)圖.png

那ActivityManager是怎么跟ActivityManagerService通信的呢?###

我們以ActivityManager的一個(gè)方法為例子看一下就行了,例如獲取最近任務(wù)的方法ActivityManager.getRecentTasks

    public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
            throws SecurityException {
        try {
            return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
                    flags, UserHandle.myUserId());
        } catch (RemoteException e) {
            // System dead, we will be dead too soon!
            return null;
        }
    }

進(jìn)入ActivityManagerNative的getDefault()方法,方法返回一個(gè)IActivityManager的單例,IActivityManager是一個(gè)接口,繼承于Interface接口。IActivityManager 的實(shí)現(xiàn)是ActivityManagerProxy,所以方法其實(shí)是返回一個(gè) ActivityManagerProxy的單例對象。這是一個(gè)代理對象,用于跟ActivityManagerService進(jìn)行binder通信。
套路差不多都這樣
1.ServiceManager.getService獲取到Ibinder
2.通過asInterface獲取到遠(yuǎn)程服務(wù)的本地代理。

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
}

    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }

ActivityManagerNative相當(dāng)于aidl通信中的stub的角色,stub繼承于binder,專門用于binder通信。ActivityManagerService會(huì)繼承于這個(gè)stub。
很多地方都可以看到這個(gè)stub,這個(gè)stub可以看作一個(gè)中間者的角色吧。這個(gè)中間者里面包含著本地代理的類定義,同時(shí)這個(gè)中間者被遠(yuǎn)端服務(wù)所繼承。

IActivityManager是本地代理和遠(yuǎn)端服務(wù)都要實(shí)現(xiàn)的接口,就是說本地代理里面的方法要和遠(yuǎn)端服務(wù)的方法一一對應(yīng)。

首先ActivityManagerService會(huì)發(fā)布本地的接口,通過ActivityManagerNative的構(gòu)造方法發(fā)布了,接口用descriptor標(biāo)示,在IActivityManager定義,String descriptor = "android.app.IActivityManager";

  public ActivityManagerNative() {
      attachInterface(this, descriptor);
  }

然后通過Binder的queryLocalInterface可以找到本地對應(yīng)的接口,這個(gè)接口的引用被代理所持有,所以代理就可以使用這個(gè)本地接口跟遠(yuǎn)端服務(wù)通信了。

        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);

代理每次調(diào)用方法,都會(huì)調(diào)用到這個(gè)本地接口transact方法,把參數(shù)跨進(jìn)程發(fā)送到遠(yuǎn)端服務(wù),遠(yuǎn)端服務(wù)通過onTransact方法,調(diào)用到實(shí)際的方法。

上面的說法有些逆向,為了正向理解,我們想想基于binder通信你會(huì)怎么寫呢?
首先整個(gè)架構(gòu)要有兩個(gè)要素
1.遠(yuǎn)端服務(wù)
2.本地代理
所以有了兩個(gè)類,遠(yuǎn)端服務(wù)ActivityManagerService,本地代理ActivityManagerProxy。

遠(yuǎn)端服務(wù)和本地代理肯定要實(shí)現(xiàn)同樣的方法嘛,所有最好設(shè)計(jì)一個(gè)接口給兩者實(shí)現(xiàn)。所以設(shè)計(jì)一個(gè)接口IActivityManager。

ActivityManagerService為了能夠遠(yuǎn)程被調(diào)用到,必須繼承于Binder類。所以這時(shí)ActivityManagerService既要繼承binder,也要實(shí)現(xiàn)IActivityManager。因?yàn)橛衎inder發(fā)布本地接口等操作,把這些東西寫到ActivityManagerService會(huì)讓文件很難看。所以干脆新建立一個(gè)stub類ActivityManagerNative類好了,里面包含一些發(fā)布本地接口的操作。順便在這個(gè)stub類定義代理類好了,節(jié)省一個(gè)文件。

幾個(gè)類的關(guān)系圖

類關(guān)系.png

參考文章:
http://blog.csdn.net/u012950099/article/details/51987036
android的aidl-手動(dòng)實(shí)現(xiàn)aidl自動(dòng)生成的Java文件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android跨進(jìn)程通信IPC整體內(nèi)容如下 1、Android跨進(jìn)程通信IPC之1——Linux基礎(chǔ)2、Andro...
    隔壁老李頭閱讀 12,497評論 11 56
  • 毫不夸張地說,Binder是Android系統(tǒng)中最重要的特性之一;正如其名“粘合劑”所喻,它是系統(tǒng)間各個(gè)組件的橋梁...
    weishu閱讀 18,129評論 29 246
  • 原文:http://weishu.me/2016/01/12/binder-index-for-newer/ 要點(diǎn)...
    指尖流逝的青春閱讀 2,685評論 0 13
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,688評論 19 139
  • 簡單說Binder Binder算是Android中比較難懂的一部分內(nèi)容了,但是非常的重要,要想研究Framewo...
    EsonJack閱讀 1,707評論 0 4

友情鏈接更多精彩內(nèi)容