日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

android AIDL IPC深入分析

發布時間:2023/11/27 生活经验 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android AIDL IPC深入分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

深入分析AIDL原理

  • 博客分類:
  • Android

在上一篇文章(Service使用方式)中,介紹了Android進程間通信(IPC)的使用,并給出了一個示例。但并沒有深入分析aidl是怎樣可以做到進程間通信的,它的執行過程是怎樣的?

這篇文章來分析IRemoteService.aidl的執行過程,并理解aidl是怎樣跨進程通信的。

?

當我們創建IRemoteService.aidl文件時,IDE會為我們在gen目錄中創建相應的文件。

?

?

Iremoteservice.java代碼 ?
  1. /**?This?file?is?auto-generated.??DO?NOT?MODIFY.??
  2. ?*?Original?file:?F:\\workspace\\AndroidImprove\\src\\com\\example\\aidl\\IRemoteService.aidl??
  3. ?*/??
  4. package?com.example.aidl;??
  5. public?interface?IRemoteService?extends?android.os.IInterface??
  6. {??
  7. /**?Local-side?IPC?implementation?stub?class.?*/??
  8. public?static?abstract?class?Stub?extends?android.os.Binder?implements?com.example.aidl.IRemoteService??
  9. {??
  10. private?static?final?java.lang.String?DESCRIPTOR?=?"com.example.aidl.IRemoteService";??
  11. /**?Construct?the?stub?at?attach?it?to?the?interface.?*/??
  12. public?Stub()??
  13. {??
  14. this.attachInterface(this,?DESCRIPTOR);??
  15. }??
  16. /**??
  17. ?*?Cast?an?IBinder?object?into?an?com.example.aidl.IRemoteService?interface,??
  18. ?*?generating?a?proxy?if?needed.??
  19. ?*/??
  20. public?static?com.example.aidl.IRemoteService?asInterface(android.os.IBinder?obj)??
  21. {??
  22. if?((obj==null))?{??
  23. return?null;??
  24. }??
  25. android.os.IInterface?iin?=?(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);??
  26. if?(((iin!=null)&&(iin?instanceof?com.example.aidl.IRemoteService)))?{??
  27. return?((com.example.aidl.IRemoteService)iin);??
  28. }??
  29. return?new?com.example.aidl.IRemoteService.Stub.Proxy(obj);??
  30. }??
  31. public?android.os.IBinder?asBinder()??
  32. {??
  33. return?this;??
  34. }??
  35. @Override?public?boolean?onTransact(int?code,?android.os.Parcel?data,?android.os.Parcel?reply,?int?flags)?throws?android.os.RemoteException??
  36. {??
  37. switch?(code)??
  38. {??
  39. case?INTERFACE_TRANSACTION:??
  40. {??
  41. reply.writeString(DESCRIPTOR);??
  42. return?true;??
  43. }??
  44. case?TRANSACTION_register:??
  45. {??
  46. data.enforceInterface(DESCRIPTOR);??
  47. com.example.aidl.IRemoteCallback?_arg0;??
  48. _arg0?=?com.example.aidl.IRemoteCallback.Stub.asInterface(data.readStrongBinder());??
  49. this.register(_arg0);??
  50. reply.writeNoException();??
  51. return?true;??
  52. }??
  53. case?TRANSACTION_unregister:??
  54. {??
  55. data.enforceInterface(DESCRIPTOR);??
  56. com.example.aidl.IRemoteCallback?_arg0;??
  57. _arg0?=?com.example.aidl.IRemoteCallback.Stub.asInterface(data.readStrongBinder());??
  58. this.unregister(_arg0);??
  59. reply.writeNoException();??
  60. return?true;??
  61. }??
  62. case?TRANSACTION_execute:??
  63. {??
  64. data.enforceInterface(DESCRIPTOR);??
  65. this.execute();??
  66. reply.writeNoException();??
  67. return?true;??
  68. }??
  69. case?TRANSACTION_getStatus:??
  70. {??
  71. data.enforceInterface(DESCRIPTOR);??
  72. java.lang.String?_arg0;??
  73. _arg0?=?data.readString();??
  74. int?_result?=?this.getStatus(_arg0);??
  75. reply.writeNoException();??
  76. reply.writeInt(_result);??
  77. return?true;??
  78. }??
  79. }??
  80. return?super.onTransact(code,?data,?reply,?flags);??
  81. }??
  82. private?static?class?Proxy?implements?com.example.aidl.IRemoteService??
  83. {??
  84. private?android.os.IBinder?mRemote;??
  85. Proxy(android.os.IBinder?remote)??
  86. {??
  87. mRemote?=?remote;??
  88. }??
  89. public?android.os.IBinder?asBinder()??
  90. {??
  91. return?mRemote;??
  92. }??
  93. public?java.lang.String?getInterfaceDescriptor()??
  94. {??
  95. return?DESCRIPTOR;??
  96. }??
  97. //注冊回調??
  98. ??
  99. public?void?register(com.example.aidl.IRemoteCallback?callback)?throws?android.os.RemoteException??
  100. {??
  101. android.os.Parcel?_data?=?android.os.Parcel.obtain();??
  102. android.os.Parcel?_reply?=?android.os.Parcel.obtain();??
  103. try?{??
  104. _data.writeInterfaceToken(DESCRIPTOR);??
  105. _data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));??
  106. mRemote.transact(Stub.TRANSACTION_register,?_data,?_reply,?0);??
  107. _reply.readException();??
  108. }??
  109. finally?{??
  110. _reply.recycle();??
  111. _data.recycle();??
  112. }??
  113. }??
  114. //取消注冊回調??
  115. ??
  116. public?void?unregister(com.example.aidl.IRemoteCallback?callback)?throws?android.os.RemoteException??
  117. {??
  118. android.os.Parcel?_data?=?android.os.Parcel.obtain();??
  119. android.os.Parcel?_reply?=?android.os.Parcel.obtain();??
  120. try?{??
  121. _data.writeInterfaceToken(DESCRIPTOR);??
  122. _data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));??
  123. mRemote.transact(Stub.TRANSACTION_unregister,?_data,?_reply,?0);??
  124. _reply.readException();??
  125. }??
  126. finally?{??
  127. _reply.recycle();??
  128. _data.recycle();??
  129. }??
  130. }??
  131. //執行回調??
  132. ??
  133. public?void?execute()?throws?android.os.RemoteException??
  134. {??
  135. android.os.Parcel?_data?=?android.os.Parcel.obtain();??
  136. android.os.Parcel?_reply?=?android.os.Parcel.obtain();??
  137. try?{??
  138. _data.writeInterfaceToken(DESCRIPTOR);??
  139. mRemote.transact(Stub.TRANSACTION_execute,?_data,?_reply,?0);??
  140. _reply.readException();??
  141. }??
  142. finally?{??
  143. _reply.recycle();??
  144. _data.recycle();??
  145. }??
  146. }??
  147. //獲取狀態??
  148. ??
  149. public?int?getStatus(java.lang.String?flag)?throws?android.os.RemoteException??
  150. {??
  151. android.os.Parcel?_data?=?android.os.Parcel.obtain();??
  152. android.os.Parcel?_reply?=?android.os.Parcel.obtain();??
  153. int?_result;??
  154. try?{??
  155. _data.writeInterfaceToken(DESCRIPTOR);??
  156. _data.writeString(flag);??
  157. mRemote.transact(Stub.TRANSACTION_getStatus,?_data,?_reply,?0);??
  158. _reply.readException();??
  159. _result?=?_reply.readInt();??
  160. }??
  161. finally?{??
  162. _reply.recycle();??
  163. _data.recycle();??
  164. }??
  165. return?_result;??
  166. }??
  167. }??
  168. static?final?int?TRANSACTION_register?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?0);??
  169. static?final?int?TRANSACTION_unregister?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?1);??
  170. static?final?int?TRANSACTION_execute?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?2);??
  171. static?final?int?TRANSACTION_getStatus?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?3);??
  172. }??
  173. //注冊回調??
  174. ??
  175. public?void?register(com.example.aidl.IRemoteCallback?callback)?throws?android.os.RemoteException;??
  176. //取消注冊回調??
  177. ??
  178. public?void?unregister(com.example.aidl.IRemoteCallback?callback)?throws?android.os.RemoteException;??
  179. //執行回調??
  180. ??
  181. public?void?execute()?throws?android.os.RemoteException;??
  182. //獲取狀態??
  183. ??
  184. public?int?getStatus(java.lang.String?flag)?throws?android.os.RemoteException;??
  185. }??

?

?

在ClientActivity綁定遠程Service并建立連接時會調用ServiceConnection.onServiceConnected(ComponentName name, IBinder service)

?

Java代碼 ?
  1. public?void?onServiceConnected(ComponentName?name,?IBinder?service)?{??
  2. ????????????remoteService?=?IRemoteService.Stub.asInterface(service);??
  3. ????????????//注冊回調??
  4. ????????????try?{??
  5. ????????????????remoteService.register(remoteCallback);??
  6. ????????????}?catch?(RemoteException?e)?{??
  7. ????????????????e.printStackTrace();??
  8. ????????????}??
  9. }??

?

?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代碼 ?
  1. //獲取狀態??
  2. ??
  3. public?int?getStatus(java.lang.String?flag)?throws?android.os.RemoteException??
  4. {??
  5. android.os.Parcel?_data?=?android.os.Parcel.obtain();??
  6. android.os.Parcel?_reply?=?android.os.Parcel.obtain();??
  7. int?_result;??
  8. try?{??
  9. _data.writeInterfaceToken(DESCRIPTOR);??
  10. _data.writeString(flag);??
  11. mRemote.transact(Stub.TRANSACTION_getStatus,?_data,?_reply,?0);??
  12. _reply.readException();??
  13. _result?=?_reply.readInt();??
  14. }??
  15. finally?{??
  16. _reply.recycle();??
  17. _data.recycle();??
  18. }??
  19. return?_result;??
  20. }??

?這一過程是把Client端的參數轉換成Parcel(_data)傳遞到Server端,而在Server端又會把返回數據保存到_reply中,這就形成了一次交互。

?

?

mRemote是遠程對象,transact方法會執行onTransact方法

?

Java代碼 ?
  1. public?final?boolean?transact(int?code,?Parcel?data,?Parcel?reply,??
  2. ????????????int?flags)?throws?RemoteException?{??
  3. ????????if?(Config.LOGV)?Log.v("Binder",?"Transact:?"?+?code?+?"?to?"?+?this);??
  4. ????????if?(data?!=?null)?{??
  5. ????????????data.setDataPosition(0);??
  6. ????????}??
  7. ????????boolean?r?=?onTransact(code,?data,?reply,?flags);??
  8. ????????if?(reply?!=?null)?{??
  9. ????????????reply.setDataPosition(0);??
  10. ????????}??
  11. ????????return?r;??
  12. ????}??

?這樣就會執行遠程的onTransact方法,

?

?

Java代碼 ?
  1. case?TRANSACTION_getStatus:??
  2. {??
  3. data.enforceInterface(DESCRIPTOR);??
  4. java.lang.String?_arg0;??
  5. _arg0?=?data.readString();??
  6. int?_result?=?this.getStatus(_arg0);??
  7. reply.writeNoException();??
  8. reply.writeInt(_result);??
  9. return?true;??
  10. }??

注意 int _result = this.getStatus(_arg0);,這就調用了Server端的getStatus(String flag),并把返回結果寫到Client端的代理Proxy對象的_reply中

?

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

PS: aidl通信有點復雜,但仔細分析并不是很難

總結

以上是生活随笔為你收集整理的android AIDL IPC深入分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。