深入分析AIDL原理
在上一篇文章(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通信有点复杂,但仔细分析并不是很难
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。