android中Stub Proxy答疑

來源:互聯網
上載者:User

標籤:

      在上篇添加賬戶源碼解析的博文中,我們發現功能是由AccountManager的mService成員來實現。而mService其實是AccountManagerService,如果對android系統有瞭解的話一定會發現AccountManagerService是運行在SystemServer進程中(所有的系統服務都是運行在SystemServer中,若SystemServer掛掉則會導致Zygote掛掉繼而android系統重啟),AccountManager是運行在setting的app中,那他們跨進程是如何通訊的呢。android的IPC是binder,本文不討論底層通訊只講解binder上層是如何構建的,還是添加賬戶代碼為例(android4.4)

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

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編譯後才有的,源碼中是沒有的:

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函數繼而來執行

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函數

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中的,且會去註冊這些服務:

 ///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之間的關係是這樣的


  AccountManager擷取到一個類型為IAccountManager.Stub.Proxy的mService;AccountManagerService(即IAccountManager.Stub)通過onTransact會接收mService發過來的命令和參數,這就是AccountManager和AccountManagerService互動的流程。當然到此為止並沒有分析到IBinder究竟是什麼,但我們至少理解Stub和Proxy代表什麼:Stub=Service,Proxy= Service代理,client(app)可以通過Proxy和Service互動。

 

 

參考資料:

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

2、Android深入淺出之Binder機制

3、Android 添加系統服務

 

android中Stub Proxy答疑

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.