最近了解了一些关于AIDL(Android Interface Definition Language)的知识,在此通过模仿AIDL进程间通信的原理加深印象。
首先我们定义两个进程通信使用的接口:
1 | public interface MyRemoteInterface extends IInterface { |
这个接口继承自IInterface(IInterface是Binder中接口的基类,所有Binder的接口都要继承它),里面定义了一个我们的方法myFunction,并含有两个静态常量用于表示该接口与该方法。
Binder的进程间通信模型是C/S模式,接下来我们在Server进程实现该接口:
1 | public class MyIRemoteService extends Binder implements MyRemoteInterface { |
由于MyIRemoteService是Server进程中的通信对象,因此它是一个实体的对象。我们在其构造函数中进行了接口注册,实现了 MyRemoteInterface 中的 asBinder 与 myFunction 两个方法。我们重写了onTransact方法,当Client进程中的代理对象通过transact方法传输数据时,我们判断是否需要执行我们的myFunction方法并返回结果。
我们在Service的onBind方法返回我们的MyIRemoteService对象:
1 | public class MyRemoteService extends Service { |
Service的注册xml如下:
1 | <service |
接下来我们来实现Client进程的通信对象:
1 | public class MyIRemoteServiceProxy implements MyRemoteInterface { |
由于MyIRemoteServiceProxy是存在于Client进程中的通信对象,因此一般而言它并不是一个实体对象,而是一个代理对象。我们在其构造函数中保存了具有通信能力的IBinder对象,在调用myFunction时,通过transact方法识别要调用的接口与具体方法,并获取Server进程onTransact方法返回的结果。
在Client进程的Activity中,调用过程如下:
1 | public class MyActivity extends Activity { |
此处我们直接给Server进程发送了一条字符串并打印,效果如下:
上图中Client进程pid为883,tid为883
Server进程pid为830,主线程tid为830,处理Binder通信子线程tid为841