AIDL
- 创建一个接口,再里面定义方法
1 | package com.example.taidl; |
build一下gen目录下会生成ICalcAIDL.java文件
1 | /* |
- 新建一个Service
1 | package com.example.taidl; |
创建了一个mBinder对象,并在Service的onBind方法中返回
注册:
1 | <service android:name="com.example.taidl.CalcService"> |
我们一会会在别的应用程序中通过Intent来查找此Service;这个不需要Activity,所以我也就没写Activity,安装完成也看不到安装图标,悄悄在后台运行着。服务端编写完毕。下面开始编写客户端:
1 | package com.example.tclient; |
将服务端的aidl文件完整的复制过来,包名一定要一致。
分析AIDL生成的代码
- 服务端
1 | private final ICalcAIDL.Stub mBinder = new ICalcAIDL.Stub() |
ICalcAILD.Stub来执行的,让我们来看看Stub这个类的声明:
1 | public static abstract class Stub extends android.os.Binder implements com.zhy.calc.aidl.ICalcAIDL |
清楚的看到这个类是Binder的子类,是不是符合我们文章开通所说的服务端其实是一个Binder类的实例
接下来看它的onTransact()方法:
1 | public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException |
文章开头也说到服务端的Binder实例会根据客户端依靠Binder驱动发来的消息,执行onTransact方法,然后由其参数决定执行服务端的代码。
可以看到onTransact有四个参数
code , data ,replay , flags
- code 是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法
- data客户端传递过来的参数
- replay服务器返回回去的值
- flags标明是否有返回值,0为有(双向),1为没有(单向)
我们仔细看case TRANSACTION_min中的代码
data.enforceInterface(DESCRIPTOR);
与客户端的writeInterfaceToken对用,标识远程服务的名称
1 | int _arg0; |
接下来分别读取了客户端传入的两个参数
1 | int _result = this.min(_arg0, _arg1); |
然后执行this.min,即我们实现的min方法;返回result由reply写回。
add同理,可以看到服务端通过AIDL生成Stub的类,封装了服务端本来需要写的代码。
客户端
客户端主要通过ServiceConnected与服务端连接
1 | private ServiceConnection mServiceConn = new ServiceConnection() |
如果你比较敏锐,应该会猜到这个onServiceConnected中的IBinder实例,其实就是我们文章开通所说的Binder驱动,也是一个Binder实例
在ICalcAIDL.Stub.asInterface中最终调用了:
1 | return new com.zhy.calc.aidl.ICalcAIDL.Stub.Proxy(obj); |
这个Proxy实例传入了我们的Binder驱动,并且封装了我们调用服务端的代码,文章开头说,客户端会通过Binder驱动的transact()方法调用服务端代码
直接看Proxy中的add方法
1 | @Override public int add(int x, int y) throws android.os.RemoteException |
首先声明两个Parcel对象,一个用于传递数据,一个用户接收返回的数据
1 | _data.writeInterfaceToken(DESCRIPTOR);与服务器端的enforceInterfac对应 |
终于看到了我们的transact方法,第一个对应服务端的code,_data,_repay分别对应服务端的data,reply,0表示是双向的
1 | _reply.readException(); |
最后读出我们服务端返回的数据,然后return。可以看到和服务端的onTransact基本是一行一行对应的。
我们已经通过AIDL生成的代码解释了Android Binder框架的工作原理。Service的作用其实就是为我们创建Binder驱动,即服务端与客户端连接的桥梁。