android跨进程通信(IPC)——AIDL
转载请标明出处:
http://blog.csdn.net/sinat_15877283/article/details/51026711;
本文出自: 【温利东的博客】
近期在看 @任玉刚 大神编写的《android开发艺术探索》。让我受益良多,以此来巩固一下我的学习成果。以下我将从一下几个方面写一下我对AIDL的一些简单认识。
AIDL 简单概念
什么是AIDL呢?AIDL的Android官方定义例如以下:
AIDL (Android Interface Definition Language) is similar to other IDLs you might have worked with. It allows you to define the programming interface that both the client and service agree upon in order to communicate with each other using interprocess communication (IPC). On Android, one process cannot normally access the memory of another process. So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.
AIDL(Android Interface Definition Language,Android 接口定义语言) Android系统平台的接口定义语言与您可能已经使用过的其它IDLs接口定义语言类似。
程序猿能够利用AIDL自己定义编程接口。在client和服务端之间实现进程间通信(IPC)。在Android平台上。一个进程通常不能訪问另外一个进程的内存空间,因此,Android平台将这些跨进程訪问的对象分解成操作系统能够识别的简单对象, 而且为跨应用訪问而特殊编排和整理这些对象。
用于编排和整理这些对象的代码编写起来很冗长,所以Android的AIDL提供了相关工具来自己主动生成这些代码供程序猿使用。
AIDL的作用
假设在一个进程中(比如Activity)要调用还有一个进程中(比如Service)对象的操作,就能够使用AIDL生成可序列化的參数。
AIDL IPC机制是面向接口的。像COM或Corba一样,可是更加轻量级。
它是使用代理类在client和实现端传递数据。
AIDL的使用场合
仅仅有你同意client从不同的应用程序为了进程间的通信而去訪问你的service,以及想在你的service处理多线程。假设不须要进行不同应用程序间的并发通信(IPC)。you should create your interface by implementing a Binder
;或者你想进行IPC。但不须要处理多线程的,则implement your interface using a Messenger
。
參考:IPC、Binder、AIDL与Intent之间差别与联系
AIDL的使用
服务端
首先要创建一个Service用来监听client的连接请求。然后创建一个AIDL文件,将暴露给client的接口在这个AIDL文件里说明,最后在Service中实现这个AIDL接口就可以。
client
要做的事情:绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转化成AIDL接口所属的类型,接下来就能够调用AIDL中的方法了。
详细AIDL的用法我也就不在又一次造轮子了,请參考:使用AIDL
须要掌握的知识点
- binder的基本使用与原理
- Service的基本使用:Android 中的 Service 全面总结
- AIDL支持的数据类型
- 基本数据类型(int、long、char、boolean、double等)
- String和CharSequence
- List:仅仅支持ArrayList。里面每一个元素都必须被AIDL支持;
- Map:仅仅支持HaspMap。里面每一个元素都必须被AIDL支持,包含key和value;
- Parcelable:全部实现了Parcelable接口的对象
- AIDL:全部AIDL接口本身也能够在AIDL文件里使用
- CopyOnWriteArrayList (支持并发读写)
- RemoteCallBackListb(删除跨进程listener的接口)
- 怎样开启多进程:http://blog.csdn.net/sinat_15877283/article/details/50824639
注意点
AIDL包结构须要在服务端和client保持一致
Parcelable对象必须要有同名的AIDL文件
- 应该增加权限验证
默认情况下,我们的远程服务不论什么人都能够连接,但这应该不是我们愿意看到的,所以我们必须给服务增加权限验证功能,权限认证失败则无法调用服务中的方法。
- Service.onBind方法中进行权限认证
- Binder.Stub(){ void onTransact() } 方法内进行权限认证
public class XxxService extends Service {
.....
private Binder mBinder = new IBookManager.Stub() {
//在这里能够做权限认证。return false意味着client的调用就会失败
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
// todo 验证条件
return super.onTransact(code, data, reply, flags);
}
......
};
@Override
public IBinder onBind(Intent intent) {
// todo 验证条件
return mBinder;
}
......
}
- 注意使用线程。避免ANR程序无响应
最后附上我的demo(临时没有审核通过。有须要的能够先给我留邮箱),
demo内除了简单的实现了client与服务端之间的进程通信。
还增加了服务端对client连接的权限认证,以及有效的解除client对服务端的监听注冊。
參考:http://book.51cto.com/art/201212/374958.htm
http://www.cnblogs.com/over140/archive/2011/03/08/1976890.html
http://blog.csdn.net/singwhatiwanna/article/details/17041691
http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html
binder: http://blog.csdn.net/cauchyweierstrass/article/details/50701102