標籤:
在上篇添加賬戶源碼解析的博文中,我們發現功能是由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答疑