面试常客——————Binder学习笔记(一)

来源:互联网 发布:孙笑川 知乎 编辑:程序博客网 时间:2024/05/23 19:52

看了网站一些关于的Binder资源和书本,现在来做一个笔记。

 对于Binder的介绍,笔者会分为两部分,第一部分为Binder的使用以及上层原理,第二部分将探讨部分Binder底层细节。

直观来说,Binder是Android中的一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通信方式在Linux中没有;

从Android Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager等等)和相应ManagerService的桥梁:

从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务

 AIDL(Android Interface Define Language) 是IPC进程间通信方式的一种.用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码.

下面介绍针对内部类Stub和Stub的内部代理类

1.DESCRIPTOR

Binder的唯一标识

2.asInterface(android.os.IBinder obj)

用于将服务端的Binder对象转换成客户端所需的AIDL接口类型的对象,这种转换过程是区分进程的,如果客户端和服务端位于同一进程,那么此方法返回的就是服务端的Stub对象本身,否则返回的是系统封装后的Stub.proxy对象

3.asBinder

此方法用于返回当前Binder对象

4.onTransact

这个方法运行在服务端的Binder线程池当中,当客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法来处理。

该方法原型为public Boolean onTransact(int code,android .os.Parcel data,android.os.Parcel reply,int flags).服务器通过code可以确定客户端所请求的目标方法是什么,接着从data中取出目标方法所需的参数(如果目标方法有参数的话),然后执行目标方法。当目标方法执行完毕后,就向reply中写入返回值(如果目标方法有返回值的话)

注意!!当位于不同进程时

调用Proxy#+方法(实现接口的方法)

这个方法运行在客户端,当客户端调用此方法时,它的内部实现是这样的:首先创建该方法所需要的输入型Parcel对象_data、输出型Parcel 对象_reply和返回值对象List;然后把该方法的参数信息写入_data中,(如果有参数的话);接着调用transact方法来发起PRC(远程过程调用)请求,同时当前线程挂起;然后服务端的onTransact方法会被调用,直到PRC过程返回后,当前线程继续执行,并从_reply中取出RPC过程的返回结果;最后返回_reply中的数据。



接下来,Binder还有两个很重要的方法linkToDeath和unlinkToDeath。

Binder运行在服务端进程,如果服务端进程由于某种原因异常终止,这个时候我们到服务端的Binder连接断裂(称之为Binder死亡),会导致我们的远程调用失败。更为关键的是,如果我们不知道Binder连接已经断裂,那么客户端的功能就会受到影响。所以通过linkToDeath我们可以给Binder设置一个死亡代理,当Binder死亡时,我们就会收到同志,这个时候我们就可以重新发起连接请求而恢复连接。

Binder设置死亡代理的步骤

1.声明一个DeathRecipient对象。DeathRecipient是一个接口,其内部只有一个方法binderDied,我们需要实现这个方法,当Binder死亡的时候,系统就会回调binderDied方法,然后我们就可以移出之前绑定的binder代理并重新绑定远程服务

2在客户端绑定远程服务成功后,给binder设置死亡代理:

binder.linkToDeath(mDeathRecipient,0);

第二个参数为标记位,我们直接设置0即可;


以上为IPC的基础知识


参考:《Android艺术与探索》




阅读全文
1 0