AIDL生成的类解析
来源:互联网 发布:怎么在淘宝上找货源 编辑:程序博客网 时间:2024/05/18 03:40
AIDL生成的类解析
首先我们有一个如下的AIDL文件:
import com.xsx.ipcdemo.Booker;interface IBookManager { List<Booker> getBookList(); void addBook(in Booker booker);}
那么系统会在工程目录的build/generated/aidl/com/xsx/ipcdemo/aidl路径下面给我们生成如下的一个类文件:(具体路径视你的包名而定)
这是一个好长好长的东西,先稍微掠一眼
public interface IBookManager extends android.os.IInterface {/** * Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.xsx.ipcdemo.IBookManager { private static final java.lang.String DESCRIPTOR = "com.xsx.ipcdemo.IBookManager"; /** * Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.xsx.ipcdemo.IBookManager interface, * generating a proxy if needed. */ public static com.xsx.ipcdemo.IBookManager asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.xsx.ipcdemo.IBookManager))) { return ((com.xsx.ipcdemo.IBookManager) iin); } return new com.xsx.ipcdemo.IBookManager.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getBookList: { data.enforceInterface(DESCRIPTOR); java.util.List<com.xsx.ipcdemo.Booker> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); com.xsx.ipcdemo.Booker _arg0; if ((0 != data.readInt())) { _arg0 = com.xsx.ipcdemo.Booker.CREATOR.createFromParcel(data); } else { _arg0 = null; } this.addBook(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.xsx.ipcdemo.IBookManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public java.util.List<com.xsx.ipcdemo.Booker> getBookList() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.util.List<com.xsx.ipcdemo.Booker> _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArrayList(com.xsx.ipcdemo.Booker.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void addBook(com.xsx.ipcdemo.Booker booker) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((booker != null)) { _data.writeInt(1); booker.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public java.util.List<com.xsx.ipcdemo.Booker> getBookList() throws android.os.RemoteException; public void addBook(com.xsx.ipcdemo.Booker booker) throws android.os.RemoteException;}
代码太多,咋们一点一点分开看。首先是如下一个接口类:
public interface IBookManager extends IInterface{ ...}
再来这个接口文件里有这么一些东西:
public interface IBookManager extends IInterface{ public static abstract class Stub extends Binder implements IBookManager{ ... } public List<Booker> getBookList() throws RemoteException; public void addBook(Booker booker) throws RemoteException;}
这么一看就很清楚了,生成的接口类IBookManager继承了IInterface接口(这里先知道所有可以在Binder中传输的接口都需要继承IInterface接口)
IBookManager里包含了一个内部类Stub,和两个方法。这两个方法是不是很眼熟,没错,就是我们之前在IBookManager.aidl文件里写的方法。
getBookList();addBook();都是待实现的方法
那么Stub又是什么,Stub继承了Binder类,说明它本身是一个Binder,现在继续看Stub里有什么内容,为了解释方便稍微调整了一下代码顺序,如下:
public static abstract class Stub extends Binder implements IBookManager{ static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); private static final String DESCRIPTOR = "com.xsx.ipcdemo.IBookManager"; public Stub() { this.attachInterface(this, DESCRIPTOR); } public static IBookManager asInterface(IBinder obj) { ... } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ... } private static class Proxy implements IBookManager{ ... }}
吓到了,Stub里这么多东西,不急,喝杯茶,一个一个看。
先看到两个整型的变量:
TRANSACTION_getBookList和TRANSACTION_addBook
干嘛用的呢,其实就是标记IBookManager接口里的两个方法,之后可以在onTransact中可以根据这个标记判断客户端所请求的是哪个方法。
DESCRIPTOR
Binder的唯一标识,一般用当前的Binder的类名表示
asInterface(IBinder obj)
用于将服务端的Binder对象转化为客户端所需的AIDL接口类型的对象;如果客户端和服务端位于同一进程,那么返回的是服务端的Stub对象本身,否则返回的是系统封装后的Stub.proxy代理对象。
public static IBookManager asInterface(IBinder obj) { if ((obj == null)) { return null; } //查找obj对象是不是存在本地进程中 IInterface iin = obj.queryLocalInterface(DESCRIPTOR); //如果存在本地进程 if (((iin != null) && (iin instanceof IBookManager))) { //返回Stub对象本身 return ((IBookManager) iin); } //否则返回代理对象 return new IBookManager.Stub.Proxy(obj);}
首先判断传入的IBinder对象是否为空,为空直接返回。
obj.queryLocalInterface(DESCRIPTOR);
根据Binder的唯一标示在当前进程里查找接口,如果接口不为空,返回接口,否则返回接口的代理
asBinder
返回当前的Binder对象。
onTransact
当客户端向服务器端发送请求时会调用该方法
@Overridepublic boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { //code指明请求的是哪个方法,每一个服务里的方法都对应一个int变量 switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getBookList: { data.enforceInterface(DESCRIPTOR); List<Booker> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); Booker _arg0; //如果有传过来参数 if ((0 != data.readInt())) { //将序列化流转化为对象 _arg0 = Booker.CREATOR.createFromParcel(data); } else { _arg0 = null; } this.addBook(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags);}
onTransact()从data参数里先取得要执行的方法所需的参数,然后执行目标方法,执行完方法之后再将方法的返回值写入reply中。如果没有带参数的话则忽略读取和写入的步骤。
在向reply回写内容前,先调用writeNoException()方法指明没有异常发生
Proxy
从名字上我们就可以看出这是个代理类,在asInterface方法中调用了,如果客户端和服务器端不在同一进程则返回该对象。
private static class Proxy implements IBookManager{ Proxy(IBinder remote) { mRemote = remote; } @Override public IBinder asBinder() { return mRemote; } public String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public List<Booker> getBookList() throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); List<Booker> _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArrayList(CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void addBook(Booker booker) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((booker != null)) { _data.writeInt(1); booker.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } }}
Binder的工作机制流程图:
具体实现类,先实现IBookManager接口,再复写方法
public class BookManager implements IBookManager{ @Override public List<Booker> getBookList() throws RemoteException { return null; } @Override public void addBook(Booker booker) throws RemoteException { } @Override public IBinder asBinder() { return null; }}
- AIDL生成的类解析
- AIDL中根目录自动生成的与aidl文件相对应的java类分析
- 深刻解析 Android 的 AIDL
- [mtk6572源码解析]ISms.aidl 生成的源码 和 SmsManagerEx 中被调用到的函数
- AIDL解析
- Aidl生成的ICalc接口文件
- AIDL自动生成源码分析以及根据自动生成的源码来自定义类实现IPC
- 深刻解析 Android 的 AIDL 介面
- 深刻解析 Android 的 AIDL 介面
- 深刻解析 Android 的 AIDL 介面
- AIDL的简单示例与解析
- Android中aidl的解析和使用
- 深入解析AIDL的实现:Messenger
- android的aidl-手动实现aidl自动生成的Java文件
- AS下生成AIDL
- AIDL解析(一)两个应用之间使用AIDL进行通信的例子
- eclipse aidl文件无法自动生成的问题
- 理解AIDL原理以及系统生成的源码
- Linux中top命令参数详解
- 希尔排序
- OpenCV 2.4.x 功能模块介绍
- android studio svn报错
- 复制介绍
- AIDL生成的类解析
- TCP/IP协议
- mysql的安装配置Linux
- 解读分库分表中间件Sharding-JDBC
- 1053: [HAOI2007]反素数ant
- 配置vimrc
- Hamilton-哈密顿回路
- java工具(三)----jsp
- 推荐!国外程序员整理的机器学习资源大全