《深入理解Android2》读书笔记(二)
接之前那篇《深入理解Android2》读书笔记(一)
下面几篇来分别详细分析
Binder类作为服务端的Bn的代表,BinderProxy类作为客户端的Bp的代表,BinderInternal类仅供Binder架构使用,GcWatcher专门用于处理和Binder架构相关的垃圾回收,Parcel类用于承载通信数据。FLAG_ONEWAY标志如果被指明,则调用方只要把请求发送到Binder驱动即可返回,而不用等待服务端的结果,是一种所谓的非阻塞方式,所以客户端一般会向服务端注册一个回调。
在java层binder正式工作之前,Native层Binder和Java层Binder需要建立关系,将会调用一些JNI函数,Binder类、BinderInternal类、BinderProxy类依次初始化。
将AMS服务注册到ServiceManager中(整个Android系统中有一个Native的ServiceManager(SM)进程,它统筹管理Android系统上的所有Service。成为一个Service的必要条件是在SM中注册)。
SM注册服务
ServiceManager
public static void addService(String name, IBinder service, boolean allowIsolated) {try {getIServiceManager().addService(name, service, allowIsolated);} catch (RemoteException e) {Log.e(TAG, "error in addService", e);} }private static IServiceManager getIServiceManager() {...// Find the service managersServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());return sServiceManager; }
BinderInternal.getContextObject函数完成了两个工作
1.创建了一个java层的binderProxy对象
2.通过JNI,该BinderProxy对象和一个Native的BpProxy对象挂钩,而该BpProxy对象的通信目标就是ServiceManager。
static public IServiceManager asInterface(IBinder obj){...IServiceManager in =(IServiceManager)obj.queryLocalInterface(descriptor);if (in != null) {return in;}return new ServiceManagerProxy(obj); }
ServiceManagerProxy
public void addService(String name, IBinder service, boolean allowIsolated)throws RemoteException {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IServiceManager.descriptor);data.writeString(name);data.writeStrongBinder(service);data.writeInt(allowIsolated ? 1 : 0);mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);reply.recycle();data.recycle(); }
addService实际添加到Parcel的并不是AMS本身,而是一个名为JavaBBinder的对象。addService正是该JavaBBinder对象最终传递到Binder驱动。
当收到请求时,系统会调用JavaBBinder的onTransact函数,最终在Binder类中实现
private boolean execTransact(int code, long dataObj, long replyObj,int flags) {Parcel data = Parcel.obtain(dataObj);Parcel reply = Parcel.obtain(replyObj);boolean res;try {res = onTransact(code, data, reply, flags);}...checkParcel(this, code, reply, "Unreasonably large binder reply buffer");reply.recycle();data.recycle();StrictMode.clearGatheredViolations();return res; }
ActivityManagerNative类实现了onTransact函数
@Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {switch (code) {case START_ACTIVITY_TRANSACTION:{data.enforceInterface(IActivityManager.descriptor);IBinder b = data.readStrongBinder();IApplicationThread app = ApplicationThreadNative.asInterface(b);String callingPackage = data.readString();Intent intent = Intent.CREATOR.createFromParcel(data);String resolvedType = data.readString();IBinder resultTo = data.readStrongBinder();String resultWho = data.readString();int requestCode = data.readInt();int startFlags = data.readInt();ProfilerInfo profilerInfo = data.readInt() != 0? ProfilerInfo.CREATOR.createFromParcel(data) : null;Bundle options = data.readInt() != 0? Bundle.CREATOR.createFromParcel(data) : null;int result = startActivity(app, callingPackage, intent, resolvedType,resultTo, resultWho, requestCode, startFlags, profilerInfo, options);reply.writeNoException();reply.writeInt(result);return true;}...
JavaBBinder仅是一个传声筒,本身不实现任何业务函数,其工作是:
1.收到请求时,简单调用它所绑定的java层binder对象的execTransact
2.该binder对象的execTransact调用其子类实现的onTransact函数
3.子类的onTransact函数将业务又派发给其子类来完成
通过这种方式,来自客户端的请求就能传递到正确的Java层Binder对象了。
AMS响应请求的流程
Java层Binder架构总结
1.对于代表客户端的BinderProxy来说,Java层的BinderProxy在Native层对应一个BpBinder对象。凡是从Java层发出的请求,首先从Java层的BinderProxy传递到Native层的BpBinder,继而由BpBinder将请求发送到Binder驱动。
2.对于代表服务端的Service来说,Java层的Binder在Native层有一个JavaBBinder对象。所有Java层的Binder在Native层都对应为JavaBBinder,而JavaBBinder仅起到中转作用,即把来自客户端的请求从Native层传递到Java层。
3.系统中依然只有一个Native的ServiceManager。
MessageQueue的部分在我的另一篇博客中已经分析过了,可移步handler机制
转载于:https://www.cnblogs.com/anni-qianqian/p/6927720.html
《深入理解Android2》读书笔记(二)相关推荐
- 深入理解JVM读书笔记二: 垃圾收集器与内存分配策略
3.2对象已死吗? 3.2.1 引用计数法 给对象添加一个引用计数器,每当有一个地方引用它的地方,计数器值+1:当引用失效,计数器值就减1;任何时候计数器为0,对象就不可能再被引用了. 它很难解决对象 ...
- 《Docker 技术入门与实践》-读书笔记二
<Docker 技术入门与实践>-读书笔记一 <Docker 技术入门与实践>-读书笔记二 一.数据管理 用户在使用 Docker 的过程中,往往需要能查看容器内应用产生的数据 ...
- 《Introduction To Modern Cryptography》读书笔记二
<Introduction To Modern Cryptography>读书笔记二 本笔记纯粹个人读书习惯与相应见解,内容归纳完全出于个人需要与个人局限,如有修改意见(比如哪儿应该是值得 ...
- oracle直查和call哪个更快,让oracle跑的更快1读书笔记二
当前位置:我的异常网» 数据库 » <>读书笔记二 <>读书笔记二 www.myexceptions.net 网友分享于:2013-08-23 浏览:9次 <> ...
- 《How Tomcat Works》读书笔记(二)
<How Tomcat Works>读书笔记(二) 这是<How Tomcat Works>第一二章的读书笔记.第一张主要写了一个静态资源处理的web服务器,第二章加了对ser ...
- 3D游戏设计读书笔记二
3D游戏设计读书笔记二 一.简答题 • 解释 游戏对象(GameObjects) 和 资源(Assets)的区别与联系. GameObjects是一个具体的实例,Assets是包括诸多游戏素材的资 ...
- 《李元芳履职记》读书笔记二 IT技术管理的沟通与团队建设
<李元芳履职记>读书笔记二 接一 https://blog.csdn.net/qq_45937199/article/details/103305223 IT技术人员从技术岗走向管理岗,所 ...
- python图像处理《数字图像处理与python实现》读书笔记二:空间滤波
文章目录 重要! 第三章 空间滤波 概览 3.1 空间滤波基础 3.1.1 空间滤波的机理 3.1.2 空间滤波器模板 3.2 平滑处理 3.2.1 平滑线性空间滤波器 3.2.2 统计排序滤波器 3 ...
- 第一行代码 Android读书笔记(二)
第一行代码 Android读书笔记 第三章 软件也要拼脸蛋-UI开发的点点滴滴 常用控件的使用方法 详解4种基本布局 自定义控件 最常用和最难用的控件-ListView 更加强大的滚动控件-Recyc ...
- 《淘宝技术这十年》读书笔记 (二).Java时代的脱胎换骨和坚若磐石
马云说过"一个好的东西往往是是说不清楚的",姑且不论这句话的对与错.但我真的很佩服<淘宝技术这十年>这本书的作者子柳,能够通过淘宝的一些故事,按照时间顺序和IT发展的各 ...
最新文章
- 等价类划分方法的应用
- 数据结构应用实例#栈#迷宫寻路
- STM32外设驱动---SysTick精准延时
- TensorFlow学习笔记(一)安装、配置、基本用法
- 地雷会炸到自己吗_回顾自己曾经的往事 ——记双语学习有感
- 网络基础: 浅析应用层一
- 工作流实战_25_flowable 流程中的自动跳过
- 手机怎么能把书签导出来_成人高考能在手机上报名吗?成人高考怎么缴费?
- 浏览器复制网页链接到微信,显示却只有网页title解决
- 使用IoC 容器清洁工厂设计模式
- ensp期末综合实验_时间表来了!洛阳中小学期末考试25日开始
- a4如何打印双面小册子_小册子打印
- linux中swap的权限,有关 Linux Swap
- 安卓调用TSC打印机打印图片
- 小波分解与小波包分解的区别
- 右耳Python小作业--快递分拣
- 解决mac按键精灵鼠标位置不准(连点器)
- PHP支付宝手机网站支付notify异步通知
- 国内域名如何转入 GoDaddy,域名转入GoDaddy要注意?
- 高级查询组件下拉框联动(三)