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_getBookListTRANSACTION_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;    }}
0 0
原创粉丝点击