RemoteCallbackList

声明

public class RemoteCallbackList<E extends IInterface>

情况

在AIDL中客户端向服务端注册一个回调方法时,服务端要考虑客户端是否意外退出(客户端因为错误应用Crash,或者被Kill掉了),服务端还不知道去回调客户端,出现错误

客户端和服务端进程状态

在进程间通信过程中,很可能出现一个进程死亡的情况。如果这时活着的一方不知道另一方已经死了就会出现问题。那我们如何在A进程中获取B进程的存活状态呢?

android肯定给我们提供了解决方式,那就是Binder的linkToDeath和unlinkToDeath方法,linkToDeath方法需要传入一个DeathRecipient对象,DeathRecipient类里面有个binderDied方法,当binder对象的所在进程死亡,binderDied方法就会被执行,我们就可以在binderDied方法里面做一些异常处理,释放资源等操作了

参考:http://www.jianshu.com/p/ce3944e5ff11

Android SDK提供一个封装好的对象:RemoteCallbackList,帮我自动处理了Link-To-Death的问题,这就帮我们剩下了很多代码了。

...

mClientCallBack = IRemoteCallBack.Stub.asInterface(callback);

if (mClientDeathHandler == null) {

mClientDeathHandler = new ClientDeathRecipient();

}

mClientCallBack.asBinder().linkToDeath(new ClientDeathRecipient(), 0);

...

private class ClientDeathRecipient implements IBinder.DeathRecipient {

@Override

public void binderDied() {

mCallbackList.unregister(mClientCallBack);

mClientCallBack = null;

Logger.d(TAG,"client  is died");

}

}

上面是在server端对client的回调接口的binder对象设置的DeathRecipient。在client死亡时,解注册client的回调,并且置空。

有注册回调就肯定有解注册,但是client端与server不在一个进程,server是无法得知client解注册时传入的回调接口是哪一个(client调用解注册时,是通过binder传输到server端,所以解注册时的回调接口是新创建的,而不是注册时的回调接口)。为了解决这个问题,android提供了RemoteCallbackList这个类来专门管理remote回调的注册与解注册。具体参考RemoteCallbackList的源码

Messenger与AIDL的异同

其实Messenger的底层也是用AIDL实现的,但用起来还是有些不同的,这里总结了几点区别:

1. Messenger本质也是AIDL,只是进行了封装,开发的时候不用再写.aidl文件。

结合我自身的使用,因为不用去写.aidl文件,相比起来,Messenger使用起来十分简单。但前面也说了,Messenger本质上也是AIDL,故在底层进程间通信这一块,两者的效率应该是一样的。

2. 在service端,Messenger处理client端的请求是单线程的,而AIDL是多线程的。

使用AIDL的时候,service端每收到一个client端的请求时,就在BInder线程池中取一个线程去执行相应的操作。而Messenger,service收到的请求是放在Handler的MessageQueue里面,Handler大家都用过,它需要绑定一个Thread,然后不断poll message执行相关操作,这个过程是同步执行的。

3. client的方法,使用AIDL获取返回值是同步的,而Messenger是异步的。

Messenger只提供了一个方法进行进程间通信,就是send(Message msg)方法,发送的是一个Message,没有返回值,要拿到返回值,需要把client的Messenger作为msg.replyTo参数传递过去,service端处理完之后,在调用客户端的Messenger的send(Message msg)方法把返回值传递回client,这个过程是异步的,而AIDL你可以自己指定方法,指定返回值,它获取返回值是同步的(如果没有用oneway修饰方法的话)。

总的来说,AIDL灵活性更高,如果需要IPC通信的地方比较多,还是更推荐自定义AIDL一点。

aidl

aidl中有onway,in,out,inout关键字修饰

oneway

正常情况下Client调用AIDL接口方法时会阻塞,直到Server进程中该方法被执行完。oneway可以修饰AIDL文件里的方法,oneway修饰的方法在用户请求相应功能时不需要等待响应可直接调用返回,非阻塞效果,该关键字可以用来声明接口或者声明方法,如果接口声明中用到了oneway关键字,则该接口声明的所有方法都采用oneway方式。(注意,如果client和Server在同一进程中,oneway修饰的方法还是会阻塞),oneway只能针对某一个接口,不能直接定义方法。 方法必须是void类型的返回值类型

in

非基本数据类型和string的参数类型必须加参数修饰符,in的意思是只输入,既最终server端执行完后不会影响到参数对象

out

与in相反,out修饰的参数只能由server写入并传递到client,而client传入的值并不会传递到server,使用out修饰,如果参数是自定义了类型,必须实现parcelable接口,并且实现public void readFromParcel(Parcel in)方法

inout

被inout修饰的参数,既可以从client传递到server,也可以server传递到client,使用out修饰,如果参数是自定义了类型,必须实现Parcelable接口,并且实现public void readFromParcel(Parcel in)方法

如果aidl中使用了自定义类型,必须实现Parcelable接口,并新建一个和自定义类型名相同的aidl,内容就是parcelable 接口名称

android aidl通信 RemoteCallbackList客户端注册回调的更多相关文章

  1. Android : App客户端与后台服务的AIDL通信以及后台服务的JNI接口实现

    一.APP客户端进程与后台服务进程的AIDL通信 AIDL(Android Interface definition language-“接口定义语言”) 是 Android 提供的一种进程间通信 ( ...

  2. Android 进程通信机制之 AIDL

    什么是 AIDL AIDL 全称 Android Interface Definition Language,即 安卓接口描述语言.听起来很深奥,其实它的本质就是生成进程间通信接口的辅助工具.它的存在 ...

  3. AIDL(2):服务端回调客户端

    1.大致流程 在服务端声明远程服务接口IRemoteService.aidl,并声明回调接口ICallback.aidl 在服务端实现远程服务接口IRemoteService.Stub 使用Remot ...

  4. Android系列之Fragment(三)----Fragment和Activity之间的通信(含接口回调)

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  5. Android——进程通信/ AIDL/Message相关知识总结贴

    Android多进程通信 http://www.apkbus.com/android-83462-1-1.html Android 跨进程通信(一) http://www.apkbus.com/and ...

  6. AIDL/IPC Android AIDL/IPC 进程通信机制——超具体解说及使用方法案例剖析(播放器)

    首先引申下AIDL.什么是AIDL呢?IPC? ------ Designing a Remote Interface Using AIDL 通常情况下,我们在同一进程内会使用Binder.Broad ...

  7. Android AIDL SERVICE 双向通信 详解

    http://www.cnblogs.com/punkisnotdead/p/5062631.html 起因 是这个blog 提到了 用webview 的时候 用开启子进程的方式 可以极大避免内存泄露 ...

  8. Aidl实现进程间通信,跨进程回调

    aidl支持的文件类型 1. Java 编程语言中的基本类型, 如 int.long.boolean 等, 不需要 import. 2. String.List.Map 和 CharSequence, ...

  9. Android aidl Binder框架浅析

      转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38461079 ,本文出自[张鸿洋的博客] 1.概述 Binder能干什么?B ...

随机推荐

  1. Jmeter_录制HTTPS

    [环境] Jmeter版本:Jmeter3.2: JDK版本:JDK1.8 [配置] [1]添加“线程组.Http信息头管理器.httpCookie管理器.HTTP代理服务器”: [2]设置浏览器的“ ...

  2. 【转】C# datagridview大小跟随窗口动态改变

    源地址:https://blog.csdn.net/fengxing11/article/details/52527715

  3. python 中文件夹的操作

    文件有两个管家属性:路径和文件名. 路径指明了文件在磁盘的位置,文件名原点的后面部分称为扩展名(后缀),它指明了文件的类型. 一:文件夹操作 Python中os 模块可以处理文件夹 1,当前工作目录 ...

  4. 【ARC075F】Mirrored 搜索/数位dp

    Description ​ 给定正整数DD,求有多少个正整数NN,满足rev(N)=N+Drev(N)=N+D,其中rev(N)rev(N)表示将NN的十进制表示翻转来读得到的数 Input ​ 一个 ...

  5. 【bzoj4176】Lucas的数论 莫比乌斯反演+杜教筛

    Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...

  6. 消息中间件ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、Kafka如何选型?

    最近要为公司的消息队列中间件进行选型,市面上相关的开源技术又非常多,如ActiveMQ.RabbitMQ.ZeroMQ.Kafka,还有阿里巴巴的RocketMQ等. 这么多技术,如何进行选型呢? 首 ...

  7. Windows Server 2008 R2中IIS7.5配置完网站权限不足问题的解决办法:

    Windows Server 2008 R2中IIS7.5配置完网站权限不足问题的解决办法:常见问题:HTTP 错误 500.0 - Internal Server Error无法显示页面,因为发生内 ...

  8. 关于 FPDF、HTML2PDF里的中文、日文、韩文等双字节字符换行问题

    最近使用 FPDF.HTML2PDF导出中文PDF,发现表格里的数据不会自动换行,格式乱了,看了一下手册,有个 functionCell()可以设置换行,但是设置了半天也没反应!最后搞了一个笨办法完美 ...

  9. ST第一章基础概念

    1.1程序由程序.数据.文档 测试对象 软件测试目的:发现尽可能多的软件缺陷,并期望通过改错把缺陷统统排除,提高软件质量 1.2 ST分类 1.2.1 方式分类 (1)静态测试 :不执行被测对象程序代 ...

  10. rest-assured的对象映射(序列化和反序列化)

    rest-assured支持映射Java对象到Json和XML以及从Json和XML中映射到Java对象.Json映射需要在classpath 中有Jackson.Jackson 2或者是Gson,X ...