android中Stub Proxy答疑

      在上篇添加帳戶源碼解析的博文中,咱們發現功能是由AccountManager的mService成員來實現。而mService實際上是AccountManagerService,若是對android系統有了解的話必定會發現AccountManagerService是運行在SystemServer進程中(全部的系統服務都是運行在SystemServer中,若SystemServer掛掉則會致使Zygote掛掉繼而android系統重啓),AccountManager是運行在setting的app中,那他們跨進程是如何通訊的呢。android的IPC是binder,本文不討論底層通訊只講解binder上層是如何構建的,仍是添加帳戶代碼爲例(android4.4)html

   ok,咱們直接來看看AccountManager和AccountManagerService類的定義。java

public class AccountManagerService extends IAccountManager.Stub
        implements RegisteredServicesCacheListener<AuthenticatorDescription> {
public class AccountManager {

  AccountManager只是個普通的類,咱們先無論;看看AccountManagerService繼承的IAccountManager.Stub是個什麼東西。但其實你找遍源碼都沒發現IAccountManager.Stub。這裏就要請出aidl(Android Interface definition language),它是一種android內部進程通訊接口的描述語言,經過它咱們能夠定義進程間的通訊接口(實質就是函數)。這裏的aidl就是IAccountManager.aidl(定義了函數),經系統編譯(看參考資料3)後生成IAccountManager.java文件。注意IAccountManager.java是要android編譯後纔有的,源碼中是沒有的:android

public interface IAccountManager extends android.os.IInterface
{         //out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/accounts/IAccountManager.java
    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements android.accounts.IAccountManager
    {
        private static final java.lang.String DESCRIPTOR = "android.accounts.IAccountManager";
        public static android.accounts.IAccountManager asInterface(android.os.IBinder obj){......}
        ......
        private static class Proxy implements android.accounts.IAccountManager{......}
        ....
    }
    ......
    // IAccountManager.aidl中聲明過的函數
}

  找到了IAccountManager.Stub的定義後咱們先不去深刻研究來看下AccountManager和AccountManagerService之間是如何關聯的。在上篇的分析中,AccountManager是經過AccountManager.get(this)來建立的,get()函數繼續調用getSystemService函數繼而來執行app

registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
                    IAccountManager service = IAccountManager.Stub.asInterface(b);
                    return new AccountManager(ctx, service);
                }})

  這幾行的代碼涉及的知識點比較多,咱們來深刻了解下。getService()向ServiceManager返回AccountManagerService的IBinder(這裏先這麼理解,稍後深刻),着重是IAccountManager.Stub.asInterface(b)這行代碼,展開asInterface函數ide

public static android.accounts.IAccountManager asInterface(android.os.IBinder obj)
{
    if ((obj==null)) {
        return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin!=null)&&(iin instanceof android.accounts.IAccountManager))) {
        return ((android.accounts.IAccountManager)iin);
    }
    return new android.accounts.IAccountManager.Stub.Proxy(obj);
}

  結合Proxy理解難度不大,它就是返回成員變量mRemote =IBinder的IAccountManager.Stub.Proxy。而後結合AccountManager構造函數知道,AccountManager.get(this)返回的是一個包含AccountManagerService Proxy的AccountManager(記住這個)。再回過頭去看AccountManagerService的IBinder是如何獲得的。
函數

 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);

  上面提到過系統提供的服務是運行在SystemServer中的,且會去註冊這些服務:this

 ///frameworks/base/services/java/com/android/server/SystemServer.java
 // The AccountManager must come before the ContentService
            try {
                // TODO: seems like this should be disable-able, but req'd by ContentService
                Slog.i(TAG, "Account Manager");
                accountManager = new AccountManagerService(context);
                ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting Account Manager", e);
            }

  代碼中將AccountManagerService服務和Context.ACCOUNT_SERVICE("account")字符串關聯,這樣能夠根據字符串來找到對應的服務了。getService(ACCOUNT_SERVICE)就獲取到了AccountManagerService的IBinder(能夠理解爲句柄吧)。故AccountManager和AccountManagerService之間的關係是這樣的spa


  AccountManager獲取到一個類型爲IAccountManager.Stub.Proxy的mService;AccountManagerService(即IAccountManager.Stub)經過onTransact會接收mService發過來的命令和參數,這就是AccountManager和AccountManagerService交互的流程。固然到此爲止並無分析到IBinder到底是什麼,但咱們至少理解Stub和Proxy表明什麼:Stub=Service,Proxy= Service代理,client(app)能夠經過Proxy和Service交互
.net

 

 

參考資料:代理

一、使用AIDL實現進程間的通訊

二、Android深刻淺出之Binder機制

三、Android 添加系統服務

相關文章
相關標籤/搜索