android学习之使用AIDL实现进程间的通讯
一般在android中,每个应用程序都有自己的进程。每一个应用程序都是运行在自己独立的进程里面的,并且进程拥有独立的内存空间,它们的数据是独立的。正常情况下,不同的进程之间一般是不能进行通讯的。
首先简单说下进程间的通信:在操作系统中,不同的进程之间的通信方式一般有:信号量,消息队列,管道等。一、信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段;二、消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。三、管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
AIDL (Android Interface Definition Language)类似于其他的IDLs(接口定义语言),用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。一般在android中,一个进程正常情况下是不能访问另一个进程的内存空间的。所以,他们需要将他们的对象分解成操作系统能够理解的状态以达到通信的目的。这样的操作对于应用程序员来说的确有点棘手,所以android提供了AIDL帮助我们来处理它。
AIDL的方式进行进程间的通信的大体步骤和绑定本地Service调用步骤类似,与绑定本地 Service不同的是,本地Service的onBind(()方法会直接把IBinder对象本身传给客户端的ServiceConection的onServiceConnected方法的第二个参数,但是这种AIDL方式只是将IBinder对象的代理传给客户端的ServiceConnecttion的onServiceConnected方法的第二个参数。
1、创建一个AIDLService工程,相当于服务器端,客户端能通过AIDL方式访问服务器端的数据
2、创建AIDL文件(把暴露的接口文件的扩展名改为AIDL文件 去掉访问修饰符 public,AIDL文件是公有的,是为多个进程共享的,所以这里没有修饰符的概念,有.java文件改过来需要将修饰符去掉,显然,AIDL是一种接口定义语言,所以AIDL文件的格式类似于接口。AIDL文件会被自动编译,会在gen文件夹中生成对应的java文件)
定义的AIDL文件:
自动生成的java文件的一部分:
注意抽象类Stub继承自Binder,并且实现了接口ICat,并且这里自动生成的静态方法asInterface方法会在后面用到。
3、创建AidlService,实现onBind方法,并在该Service中定义一个内部类继承自Stub类(该类实现了IBinder接口,同时也实现了ICat对象,通过这种方式,将远程服务中一些数据暴露给客户端,客户端拿到它就可以获取远程服务中的数据)
部分代码:
4、在清单文件中注册Service,并指定intent-filter
5、创建一个安卓工程,相当于客户端,实现对远程服务的调用
6、创建ServiceConnection对象,在onServiceConnected中获取远程服务的onBind方法返回的对象的代理
7、绑定服务,实现远程服务的调用
分别运行服务端应用和客户端应用,注意服务端可以不需要界面显示,它所提供的Service可以供其他应用访问
效果图: