android AIDL IPC深入分析
深入分析AIDL原理
- 博客分類:
- Android
在上一篇文章(Service使用方式)中,介紹了Android進程間通信(IPC)的使用,并給出了一個示例。但并沒有深入分析aidl是怎樣可以做到進程間通信的,它的執行過程是怎樣的?
這篇文章來分析IRemoteService.aidl的執行過程,并理解aidl是怎樣跨進程通信的。
?
當我們創建IRemoteService.aidl文件時,IDE會為我們在gen目錄中創建相應的文件。
?
?
Iremoteservice.java代碼 ?- /**?This?file?is?auto-generated.??DO?NOT?MODIFY.??
- ?*?Original?file:?F:\\workspace\\AndroidImprove\\src\\com\\example\\aidl\\IRemoteService.aidl??
- ?*/??
- package?com.example.aidl;??
- public?interface?IRemoteService?extends?android.os.IInterface??
- {??
- /**?Local-side?IPC?implementation?stub?class.?*/??
- public?static?abstract?class?Stub?extends?android.os.Binder?implements?com.example.aidl.IRemoteService??
- {??
- private?static?final?java.lang.String?DESCRIPTOR?=?"com.example.aidl.IRemoteService";??
- /**?Construct?the?stub?at?attach?it?to?the?interface.?*/??
- public?Stub()??
- {??
- this.attachInterface(this,?DESCRIPTOR);??
- }??
- /**??
- ?*?Cast?an?IBinder?object?into?an?com.example.aidl.IRemoteService?interface,??
- ?*?generating?a?proxy?if?needed.??
- ?*/??
- 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);??
- if?(((iin!=null)&&(iin?instanceof?com.example.aidl.IRemoteService)))?{??
- return?((com.example.aidl.IRemoteService)iin);??
- }??
- return?new?com.example.aidl.IRemoteService.Stub.Proxy(obj);??
- }??
- 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_register:??
- {??
- data.enforceInterface(DESCRIPTOR);??
- com.example.aidl.IRemoteCallback?_arg0;??
- _arg0?=?com.example.aidl.IRemoteCallback.Stub.asInterface(data.readStrongBinder());??
- this.register(_arg0);??
- reply.writeNoException();??
- return?true;??
- }??
- case?TRANSACTION_unregister:??
- {??
- data.enforceInterface(DESCRIPTOR);??
- com.example.aidl.IRemoteCallback?_arg0;??
- _arg0?=?com.example.aidl.IRemoteCallback.Stub.asInterface(data.readStrongBinder());??
- this.unregister(_arg0);??
- reply.writeNoException();??
- return?true;??
- }??
- case?TRANSACTION_execute:??
- {??
- data.enforceInterface(DESCRIPTOR);??
- this.execute();??
- reply.writeNoException();??
- return?true;??
- }??
- case?TRANSACTION_getStatus:??
- {??
- data.enforceInterface(DESCRIPTOR);??
- java.lang.String?_arg0;??
- _arg0?=?data.readString();??
- int?_result?=?this.getStatus(_arg0);??
- reply.writeNoException();??
- reply.writeInt(_result);??
- return?true;??
- }??
- }??
- return?super.onTransact(code,?data,?reply,?flags);??
- }??
- private?static?class?Proxy?implements?com.example.aidl.IRemoteService??
- {??
- private?android.os.IBinder?mRemote;??
- Proxy(android.os.IBinder?remote)??
- {??
- mRemote?=?remote;??
- }??
- public?android.os.IBinder?asBinder()??
- {??
- return?mRemote;??
- }??
- public?java.lang.String?getInterfaceDescriptor()??
- {??
- return?DESCRIPTOR;??
- }??
- //注冊回調??
- ??
- public?void?register(com.example.aidl.IRemoteCallback?callback)?throws?android.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();??
- }??
- }??
- //取消注冊回調??
- ??
- public?void?unregister(com.example.aidl.IRemoteCallback?callback)?throws?android.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();??
- }??
- }??
- //執行回調??
- ??
- public?void?execute()?throws?android.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();??
- }??
- }??
- //獲取狀態??
- ??
- public?int?getStatus(java.lang.String?flag)?throws?android.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;??
- }??
- }??
- static?final?int?TRANSACTION_register?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?0);??
- static?final?int?TRANSACTION_unregister?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?1);??
- static?final?int?TRANSACTION_execute?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?2);??
- static?final?int?TRANSACTION_getStatus?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?3);??
- }??
- //注冊回調??
- ??
- public?void?register(com.example.aidl.IRemoteCallback?callback)?throws?android.os.RemoteException;??
- //取消注冊回調??
- ??
- public?void?unregister(com.example.aidl.IRemoteCallback?callback)?throws?android.os.RemoteException;??
- //執行回調??
- ??
- public?void?execute()?throws?android.os.RemoteException;??
- //獲取狀態??
- ??
- public?int?getStatus(java.lang.String?flag)?throws?android.os.RemoteException;??
- }??
?
?
在ClientActivity綁定遠程Service并建立連接時會調用ServiceConnection.onServiceConnected(ComponentName name, IBinder service)
?
Java代碼 ?- public?void?onServiceConnected(ComponentName?name,?IBinder?service)?{??
- ????????????remoteService?=?IRemoteService.Stub.asInterface(service);??
- ????????????//注冊回調??
- ????????????try?{??
- ????????????????remoteService.register(remoteCallback);??
- ????????????}?catch?(RemoteException?e)?{??
- ????????????????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代碼 ?- //獲取狀態??
- ??
- public?int?getStatus(java.lang.String?flag)?throws?android.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代碼 ?- public?final?boolean?transact(int?code,?Parcel?data,?Parcel?reply,??
- ????????????int?flags)?throws?RemoteException?{??
- ????????if?(Config.LOGV)?Log.v("Binder",?"Transact:?"?+?code?+?"?to?"?+?this);??
- ????????if?(data?!=?null)?{??
- ????????????data.setDataPosition(0);??
- ????????}??
- ????????boolean?r?=?onTransact(code,?data,?reply,?flags);??
- ????????if?(reply?!=?null)?{??
- ????????????reply.setDataPosition(0);??
- ????????}??
- ????????return?r;??
- ????}??
?這樣就會執行遠程的onTransact方法,
?
?
Java代碼 ?- case?TRANSACTION_getStatus:??
- {??
- data.enforceInterface(DESCRIPTOR);??
- java.lang.String?_arg0;??
- _arg0?=?data.readString();??
- int?_result?=?this.getStatus(_arg0);??
- reply.writeNoException();??
- reply.writeInt(_result);??
- return?true;??
- }??
注意 int _result = this.getStatus(_arg0);,這就調用了Server端的getStatus(String flag),并把返回結果寫到Client端的代理Proxy對象的_reply中
?
到此,aidl通信過程就完成了。
PS: aidl通信有點復雜,但仔細分析并不是很難
總結
以上是生活随笔為你收集整理的android AIDL IPC深入分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求依然歌词!
- 下一篇: 微信个性签名伤感短语