在上一篇文章(Service使用方式)中,介绍了Android进程间通信(IPC)的使用,并给出了一个示例。但并没有深入分析aidl是怎样可以做到进程间通信的,它的执行过程是怎样的?

这篇文章来分析IRemoteService.aidl的执行过程,并理解aidl是怎样跨进程通信的。

当我们创建IRemoteService.aidl文件时,IDE会为我们在gen目录中创建相应的文件。


[java]view plaincopy

/**Thisfileisauto-generated.DONOTMODIFY.

*Originalfile:F:\\workspace\\AndroidImprove\\src\\com\\example\\aidl\\IRemoteService.aidl

*/

packagecom.example.aidl;

publicinterfaceIRemoteServiceextendsandroid.os.IInterface

{

/**Local-sideIPCimplementationstubclass.*/

publicstaticabstractclassStubextendsandroid.os.Binderimplementscom.example.aidl.IRemoteService

{

privatestaticfinaljava.lang.StringDESCRIPTOR="com.example.aidl.IRemoteService";

/**Constructthestubatattachittotheinterface.*/

publicStub()

{

this.attachInterface(this,DESCRIPTOR);

}

/**

*CastanIBinderobjectintoancom.example.aidl.IRemoteServiceinterface,

*generatingaproxyifneeded.

*/

publicstaticcom.example.aidl.IRemoteServiceasInterface(android.os.IBinderobj)

{

if((obj==null)){

returnnull;

}

android.os.IInterfaceiin=(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);

if(((iin!=null)&&(iininstanceofcom.example.aidl.IRemoteService))){

return((com.example.aidl.IRemoteService)iin);

}

returnnewcom.example.aidl.IRemoteService.Stub.Proxy(obj);

}

publicandroid.os.IBinderasBinder()

{

returnthis;

}

@OverridepublicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)throwsandroid.os.RemoteException

{

switch(code)

{

caseINTERFACE_TRANSACTION:

{

reply.writeString(DESCRIPTOR);

returntrue;

}

caseTRANSACTION_register:

{

data.enforceInterface(DESCRIPTOR);

com.example.aidl.IRemoteCallback_arg0;

_arg0=com.example.aidl.IRemoteCallback.Stub.asInterface(data.readStrongBinder());

this.register(_arg0);

reply.writeNoException();

returntrue;

}

caseTRANSACTION_unregister:

{

data.enforceInterface(DESCRIPTOR);

com.example.aidl.IRemoteCallback_arg0;

_arg0=com.example.aidl.IRemoteCallback.Stub.asInterface(data.readStrongBinder());

this.unregister(_arg0);

reply.writeNoException();

returntrue;

}

caseTRANSACTION_execute:

{

data.enforceInterface(DESCRIPTOR);

this.execute();

reply.writeNoException();

returntrue;

}

caseTRANSACTION_getStatus:

{

data.enforceInterface(DESCRIPTOR);

java.lang.String_arg0;

_arg0=data.readString();

int_result=this.getStatus(_arg0);

reply.writeNoException();

reply.writeInt(_result);

returntrue;

}

}

returnsuper.onTransact(code,data,reply,flags);

}

privatestaticclassProxyimplementscom.example.aidl.IRemoteService

{

privateandroid.os.IBindermRemote;

Proxy(android.os.IBinderremote)

{

mRemote=remote;

}

publicandroid.os.IBinderasBinder()

{

returnmRemote;

}

publicjava.lang.StringgetInterfaceDescriptor()

{

returnDESCRIPTOR;

}

//注册回调

publicvoidregister(com.example.aidl.IRemoteCallbackcallback)throwsandroid.os.RemoteException

{

android.os.Parcel_data=android.os.Parcel.obtain();

android.os.Parcel_reply=android.os.Parcel.obtain();

try{

_data.writeInterfaceToken(DESCRIPTOR);

_data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));

mRemote.transact(Stub.TRANSACTION_register,_data,_reply,0);

_reply.readException();

}

finally{

_reply.recycle();

_data.recycle();

}

}

//取消注册回调

publicvoidunregister(com.example.aidl.IRemoteCallbackcallback)throwsandroid.os.RemoteException

{

android.os.Parcel_data=android.os.Parcel.obtain();

android.os.Parcel_reply=android.os.Parcel.obtain();

try{

_data.writeInterfaceToken(DESCRIPTOR);

_data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));

mRemote.transact(Stub.TRANSACTION_unregister,_data,_reply,0);

_reply.readException();

}

finally{

_reply.recycle();

_data.recycle();

}

}

//执行回调

publicvoidexecute()throwsandroid.os.RemoteException

{

android.os.Parcel_data=android.os.Parcel.obtain();

android.os.Parcel_reply=android.os.Parcel.obtain();

try{

_data.writeInterfaceToken(DESCRIPTOR);

mRemote.transact(Stub.TRANSACTION_execute,_data,_reply,0);

_reply.readException();

}

finally{

_reply.recycle();

_data.recycle();

}

}

//获取状态

publicintgetStatus(java.lang.Stringflag)throwsandroid.os.RemoteException

{

android.os.Parcel_data=android.os.Parcel.obtain();

android.os.Parcel_reply=android.os.Parcel.obtain();

int_result;

try{

_data.writeInterfaceToken(DESCRIPTOR);

_data.writeString(flag);

mRemote.transact(Stub.TRANSACTION_getStatus,_data,_reply,0);

_reply.readException();

_result=_reply.readInt();

}

finally{

_reply.recycle();

_data.recycle();

}

return_result;

}

}

staticfinalintTRANSACTION_register=(android.os.IBinder.FIRST_CALL_TRANSACTION+0);

staticfinalintTRANSACTION_unregister=(android.os.IBinder.FIRST_CALL_TRANSACTION+1);

staticfinalintTRANSACTION_execute=(android.os.IBinder.FIRST_CALL_TRANSACTION+2);

staticfinalintTRANSACTION_getStatus=(android.os.IBinder.FIRST_CALL_TRANSACTION+3);

}

//注册回调

publicvoidregister(com.example.aidl.IRemoteCallbackcallback)throwsandroid.os.RemoteException;

//取消注册回调

publicvoidunregister(com.example.aidl.IRemoteCallbackcallback)throwsandroid.os.RemoteException;

//执行回调

publicvoidexecute()throwsandroid.os.RemoteException;

//获取状态

publicintgetStatus(java.lang.Stringflag)throwsandroid.os.RemoteException;

}


在ClientActivity绑定远程Service并建立连接时会调用ServiceConnection.onServiceConnected(ComponentName name, IBinder service)


[java]view plaincopy

publicvoidonServiceConnected(ComponentNamename,IBinderservice){

remoteService=IRemoteService.Stub.asInterface(service);

//注册回调

try{

remoteService.register(remoteCallback);

}catch(RemoteExceptione){

e.printStackTrace();

}

}



IBinder service是从RemoteService返回的IRemoteService.Stub iBinder,这个对象是Server应用进程中的对象。

IRemoteService.Stub.asInterface(service)在本地创建了一个代理

public static com.example.aidl.IRemoteService asInterface(android.os.IBinder obj)

{

if ((obj==null)) {

return null;

}

android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);//这里肯定返回null

if (((iin!=null)&&(iin instanceof com.example.aidl.IRemoteService))) {

return ((com.example.aidl.IRemoteService)iin);

}

return new com.example.aidl.IRemoteService.Stub.Proxy(obj);//创建一个本地代理

}

当使用remoteService调用方法时,其实是调用了本地com.example.aidl.IRemoteService.Stub.Proxy对象的方法,从Proxy方法中可以看到,每个方法都执行了mRemote.transact(Stub.TRANSACTION_xxx, _data, _reply, 0);。

如:

[java]view plaincopy

//获取状态

publicintgetStatus(java.lang.Stringflag)throwsandroid.os.RemoteException

{

android.os.Parcel_data=android.os.Parcel.obtain();

android.os.Parcel_reply=android.os.Parcel.obtain();

int_result;

try{

_data.writeInterfaceToken(DESCRIPTOR);

_data.writeString(flag);

mRemote.transact(Stub.TRANSACTION_getStatus,_data,_reply,0);

_reply.readException();

_result=_reply.readInt();

}

finally{

_reply.recycle();

_data.recycle();

}

return_result;

}


这一过程是把Client端的参数转换成Parcel(_data)传递到Server端,而在Server端又会把返回数据保存到_reply中,这就形成了一次交互。

mRemote是远程对象,transact方法会执行onTransact方法


[java]view plaincopy

publicfinalbooleantransact(intcode,Parceldata,Parcelreply,

intflags)throwsRemoteException{

if(Config.LOGV)Log.v("Binder","Transact:"+code+"to"+this);

if(data!=null){

data.setDataPosition(0);

}

booleanr=onTransact(code,data,reply,flags);

if(reply!=null){

reply.setDataPosition(0);

}

returnr;

}


这样就会执行远程的onTransact方法,


[java]view plaincopy

caseTRANSACTION_getStatus:

{

data.enforceInterface(DESCRIPTOR);

java.lang.String_arg0;

_arg0=data.readString();

int_result=this.getStatus(_arg0);

reply.writeNoException();

reply.writeInt(_result);

returntrue;

}



注意 int _result = this.getStatus(_arg0);,这就调用了Server端的getStatus(String flag),并把返回结果写到Client端的代理Proxy对象的_reply中

到此,aidl通信过程就完成了。

PS: aidl通信有点复杂,但仔细分析并不是很难