博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android中Stub Proxy答疑
阅读量:4699 次
发布时间:2019-06-09

本文共 4120 字,大约阅读时间需要 13 分钟。

      在上篇添加账户源码解析的博文中,我们发现功能是由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
{
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、

2、

3、

 

转载于:https://www.cnblogs.com/vendanner/p/5140614.html

你可能感兴趣的文章
gridview 自定义value值
查看>>
2018二月实现计划成果及其三月规划
查看>>
类名.class和getClass()区别
查看>>
12/17面试题
查看>>
LeetCode 242. Valid Anagram
查看>>
JSP表单提交乱码
查看>>
如何适应现代雇佣关系
查看>>
团队项目(第五周)
查看>>
SQL 优化经验总结34条
查看>>
开源 视频会议 收藏
查看>>
核心J2EE模式 - 截取过滤器
查看>>
.net开源CMS
查看>>
JdbcTemplate
查看>>
第一次使用maven记录
查看>>
SharePoint服务器端对象模型 之 使用CAML进展数据查询
查看>>
Building Tablet PC Applications ROB JARRETT
查看>>
Adobe® Reader®.插件开发
查看>>
【POJ 3461】Oulipo
查看>>
Alpha 冲刺 (5/10)
查看>>
使用Siege进行WEB压力测试
查看>>