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自定义编程接口,在客户端和服务端之间实现进程间通信(IPC)。在Android平台上,一个进程通常不能访问另外一个进程的内存空间,因此,Android平台将这些跨进程访问的对象分解成操作系统能够识别的简单对象, 并且为跨应用访问而特殊编排和整理这些对象。用于编排和整理这些对象的代码编写起来非常冗长,所以Android的AIDL提供了相关工具来自动生成这些代码供程序员使用。

AIDL的作用

如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。

AIDL的使用场合

只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的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用来监听客户端的连接请求,然后创建一个AIDL文件,将暴露给客户端的接口在这个AIDL文件中说明,最后在Service中实现这个AIDL接口即可。

客户端

要做的事情:绑定服务端的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包结构需要在服务端和客户端保持一致

    这里写图片描述

  • Parcelable对象必须要有同名的AIDL文件

这里写图片描述

  • 应该加入权限验证
    默认情况下,我们的远程服务任何人都可以连接,但这应该不是我们愿意看到的,所以我们必须给服务加入权限验证功能,权限认证失败则无法调用服务中的方法。
    • Service.onBind方法中进行权限认证
    • Binder.Stub(){ void onTransact() } 方法内进行权限认证
public class XxxService extends Service {
      .....
    private Binder mBinder = new IBookManager.Stub() {
        //在这里可以做权限认证,return false意味着客户端的调用就会失败
        @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内除了简单的实现了客户端与服务端之间的进程通信,
还添加了服务端对客户端连接的权限认证,以及有效的解除客户端对服务端的监听注册。

参考: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值