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 添加系统服务

相关文章
相关标签/搜索