android中Stub Proxy答疑
在上篇添加账户源码解析的博文中,我们发现功能是由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交互。
参考资料:
android中Stub Proxy答疑的更多相关文章
- Android中的Binder机制的简要理解
转载自:http://www.linuxidc.com/Linux/2012-07/66195.htm http://blog.csdn.net/sunxingzhesunjinbiao/articl ...
- Android 中的AIDL,Parcelable和远程服务
Android 中的AIDL,Parcelable和远程服务 早期在学习期间便接触到AIDL,当时对此的运用也是一撇而过.只到近日在项目中接触到AIDL,才开始仔细深入.AIDL的作用 ...
- Android 手写Binder 教你理解android中的进程间通信
关于Binder,我就不解释的太多了,网上一搜资料一堆,但是估计还是很多人理解的有困难.今天就教你如何从 app层面来理解好Binder. 其实就从我们普通app开发者的角度来看,仅仅对于androi ...
- Android 中AIDL的使用与理解
AIDL的使用: 最常见的aidl的使用就是Service的跨进程通信了,那么我们就写一个Activity和Service的跨进程通信吧. 首先,我们就在AS里面新建一个aidl文件(ps:现在AS建 ...
- Android中的Service详解
今天我们就来介绍一下Android中的四大组件中的服务Service,说到Service, 它分为本地服务和远程服务:区分这两种服务就是看客户端和服务端是否在同一个进程中,本地服务是在同一进程中的,远 ...
- 阿里面试官:Android中binder机制的实现原理及过程?
Binder 是 Android 系统中非常重要的组成部分.Android 系统中的许多功能建立在 Binder 机制之上.在这篇文章中,我们会对 Android 中的 Binder 在系统架构中的作 ...
- Android 中常见控件的介绍和使用
1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.la ...
- Android中如何控制元素的显示隐藏?
在Android程序中,有时需要程序开启时默认隐藏某个控件,当单击某个按钮时才触发显示控件的内容.比如在查询员工资料时,提交查询后再显示查询到的表格内容: Android中控制元素的隐藏参考以下代码. ...
- URL转Drawable之 Android中获取网络图片的三种方法
转载自: http://doinone.iteye.com/blog/1074283 Android中获取网络图片是一件耗时的操作,如果直接获取有可能会出现应用程序无响应(ANR:Applicatio ...
随机推荐
- AJAX基本操作
XMLHttpRequest对象: XMLHttpRequest 是 AJAX 的基础.所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject) ...
- Flask-SQLAlchemy使用
Flask-SQLAlchemy 使用起来非常有趣,对于基本应用十分容易使用,并且对于大型项目易于扩展. 官方文档:https://flask-sqlalchemy.palletsprojects.c ...
- 自己动手实现springboot运行时新增/更新外部接口
最近有个需求:需要让现有springboot项目可以加载外部的jar包实现新增.更新接口逻辑.本着拿来主义的思维网上找了半天没有找到类似的东西,唯一有点相似的还是spring-loaded但是这个东西 ...
- C# 读取Word文本框中的文本、图片和表格(附VB.NET代码)
[概述] Word中可插入文本框,在文本框中可添加文本.图片.表格等内容.本篇文章通过C#程序代码介绍如何来读取文本框中的文本.图片和表格等内容.附VB.NET代码,有需要可作参考. [程序环境] 程 ...
- 迷宫问题(DFS)
声明:图片及内容基于https://www.bilibili.com/video/BV1oE41177wk?t=3245 问题及分析 8*8的迷宫,最外周是墙,0表示可以走,1表示不可以走 设置迷宫 ...
- Java内存区域略解
概览 分述 程序计数器 用于记录该线程的执行位置,便于跳转或者线程中断后的恢复 方法区 Java虚拟机规范中把 原本用于存储常量,静态变量和类的元信息,但java1.7将字符串常量移到了堆中,java ...
- 使用 DD 命令制作 USB 启动盘
Windows 下有很多很好用的 USB 启动盘制作工具,比如 Rufus,但是 MacOS 下这个类型的工具就少了很多,这里记录下在 MacOS 中用 DD 命令制作 Linux USB 启动盘的操 ...
- IPFS挖矿赚钱吗?IPFS挖矿是真的吗?
IPFS一出现就获得了极高的关注度,「让人类信息永存」的口号也让其蒙上了一层神秘的面纱.今天我就来给大家自剖析,一探IPFS技术的真相. IPFS是一个去中心化存储网络,而Filecoin是IPFS激 ...
- Maven项目中resources配置总结
目录 背景 第一部分 基本配置介绍 第二部分 具体配置和注意事项 第三部分 读取resources资源 参考文献及资料 背景 通常Maven项目的文件目录结构如下: # Maven项目的标准目录结构 ...
- go中semaphore(信号量)源码解读
运行时信号量机制 semaphore 前言 作用是什么 几个主要的方法 如何实现 sudog 缓存 acquireSudog releaseSudog semaphore poll_runtime_S ...