分类: Android2011-11-18 17:29 6522人阅读 评论(1) 收藏 举报

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

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

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

  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. public void register(com.example.aidl.IRemoteCallback callback) throws android.os.RemoteException
  99. {
  100. android.os.Parcel _data = android.os.Parcel.obtain();
  101. android.os.Parcel _reply = android.os.Parcel.obtain();
  102. try {
  103. _data.writeInterfaceToken(DESCRIPTOR);
  104. _data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));
  105. mRemote.transact(Stub.TRANSACTION_register, _data, _reply, 0);
  106. _reply.readException();
  107. }
  108. finally {
  109. _reply.recycle();
  110. _data.recycle();
  111. }
  112. }
  113. //取消注册回调
  114. public void unregister(com.example.aidl.IRemoteCallback callback) throws android.os.RemoteException
  115. {
  116. android.os.Parcel _data = android.os.Parcel.obtain();
  117. android.os.Parcel _reply = android.os.Parcel.obtain();
  118. try {
  119. _data.writeInterfaceToken(DESCRIPTOR);
  120. _data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));
  121. mRemote.transact(Stub.TRANSACTION_unregister, _data, _reply, 0);
  122. _reply.readException();
  123. }
  124. finally {
  125. _reply.recycle();
  126. _data.recycle();
  127. }
  128. }
  129. //执行回调
  130. public void execute() throws android.os.RemoteException
  131. {
  132. android.os.Parcel _data = android.os.Parcel.obtain();
  133. android.os.Parcel _reply = android.os.Parcel.obtain();
  134. try {
  135. _data.writeInterfaceToken(DESCRIPTOR);
  136. mRemote.transact(Stub.TRANSACTION_execute, _data, _reply, 0);
  137. _reply.readException();
  138. }
  139. finally {
  140. _reply.recycle();
  141. _data.recycle();
  142. }
  143. }
  144. //获取状态
  145. public int getStatus(java.lang.String flag) throws android.os.RemoteException
  146. {
  147. android.os.Parcel _data = android.os.Parcel.obtain();
  148. android.os.Parcel _reply = android.os.Parcel.obtain();
  149. int _result;
  150. try {
  151. _data.writeInterfaceToken(DESCRIPTOR);
  152. _data.writeString(flag);
  153. mRemote.transact(Stub.TRANSACTION_getStatus, _data, _reply, 0);
  154. _reply.readException();
  155. _result = _reply.readInt();
  156. }
  157. finally {
  158. _reply.recycle();
  159. _data.recycle();
  160. }
  161. return _result;
  162. }
  163. }
  164. static final int TRANSACTION_register = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
  165. static final int TRANSACTION_unregister = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
  166. static final int TRANSACTION_execute = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
  167. static final int TRANSACTION_getStatus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
  168. }
  169. //注册回调
  170. public void register(com.example.aidl.IRemoteCallback callback) throws android.os.RemoteException;
  171. //取消注册回调
  172. public void unregister(com.example.aidl.IRemoteCallback callback) throws android.os.RemoteException;
  173. //执行回调
  174. public void execute() throws android.os.RemoteException;
  175. //获取状态
  176. public int getStatus(java.lang.String flag) throws android.os.RemoteException;
  177. }

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

  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);。

如:

  1. //获取状态
  2. public int getStatus(java.lang.String flag) throws android.os.RemoteException
  3. {
  4. android.os.Parcel _data = android.os.Parcel.obtain();
  5. android.os.Parcel _reply = android.os.Parcel.obtain();
  6. int _result;
  7. try {
  8. _data.writeInterfaceToken(DESCRIPTOR);
  9. _data.writeString(flag);
  10. mRemote.transact(Stub.TRANSACTION_getStatus, _data, _reply, 0);
  11. _reply.readException();
  12. _result = _reply.readInt();
  13. }
  14. finally {
  15. _reply.recycle();
  16. _data.recycle();
  17. }
  18. return _result;
  19. }

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

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

  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方法,

  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通信有点复杂,但仔细分析并不是很难

深入分析AIDL原理的更多相关文章

  1. 深入分析Synchronized原理(阿里面试题)

    还有一篇 讲解lock的实现原理,参考:解决多线程安全问题-无非两个方法synchronized和lock 具体原理以及如何 获取锁AQS算法 (百度-美团) 记得开始学习Java的时候,一遇到多线程 ...

  2. Android探索之旅 | AIDL原理和实例讲解

    轉載自http://www.jianshu.com/p/ef86f682a8f9 -- 作者 谢恩铭 转载请注明出处 前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Pr ...

  3. AIDL原理分析

    季春初始,天气返暖,新冠渐去,正值学习好时机.在Android系统中,AIDL一直在Framework和应用层上扮演着很重要的角色,今日且将其原理简单分析.(文2020.03.30) 一.开篇介绍 1 ...

  4. AIDL原理解析

    首先为什么需要aidl? 下面是不需要aidl 的binder的IPC通讯过程,表面上结构很简单,但是有个困难就是,客户端和服务端进行通讯,你得先将你的通讯请求转换成序列化的数据,然后调用transa ...

  5. AIDL原理之 Framewok层实现

    AIDLFramework层的架构,如下图: 换而言之,Android就是在传统的C/S架构中加入了一层,实现IPC.图中表明,AIDL类似COM的Proxy/Stub架构.不过是现在android自 ...

  6. 深入分析Synchronized原理

    前言 记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决 ...

  7. AIDL通信原理

    AIDL (Android Interface Definition Language),通过定义通信接口来实现进程间通信.这是Google提供的一种在安卓应用进程间通信的工具.所以要了解AIDL的通 ...

  8. 解决多线程安全问题-无非两个方法synchronized和lock 具体原理(百度-美团)

    还有其他的锁,如果想要了解,参考:JAVA锁机制-可重入锁,可中断锁,公平锁,读写锁,自旋锁, 用synchronized实现ReentrantLock 美团面试题参考:使用synchronized ...

  9. 【Java并发专题之三】Java线程互斥、协作原理

    (I)Java线程互斥原理之synchronized原理 从JDK5引入CAS原子操作,但没有对synchronized关键字做优化,而是增加了J.U.C.concurrent,concurrent包 ...

随机推荐

  1. SpringBoot 密码MD5加密

    public class PasswordEncrypt { public static String encodeByMd5(String string) throws NoSuchAlgorith ...

  2. 什么是Zero-Copy?

    概述 考虑这样一种常用的情形:你需要将静态内容(类似图片.文件)展示给用户.那么这个情形就意味着你需要先将静态内容从磁盘中拷贝出来放到一个内存buf中,然后将这个buf通过socket传输给用户,进而 ...

  3. 【转】和菜鸟一起学linux之DBUS基础学习记录

    [原文] D-Bus三层架构 D-Bus是一个为应用程序间通信的消息总线系统, 用于进程之间的通信.它是个3层架构的IPC 系统,包括: 1.函数库libdbus ,用于两个应用程序互相联系和交互消息 ...

  4. Linux 更改默认安装路径

    一.rpm -qal |grep mysql 二.除了根据软件包来找文件位置之外,最常用的就是通过find查找某个关键字比如mysql所有包含mysql服务的文件路径 find / -name unr ...

  5. NumPy来自现有数据的数组

    NumPy - 来自现有数据的数组 这一章中,我们会讨论如何从现有数据创建数组. numpy.asarray 此函数类似于numpy.array,除了它有较少的参数. 这个例程对于将 Python 序 ...

  6. Django开发点菜系统学习笔记

    1.使用django-simple-captcha包的时候,会调用到: register_form = RegisterForm(request.POST) 但是这个时候captcha不进行错误检验, ...

  7. Confluence 6 配置系统属性

    在这个页面中描述 Confluence 启动时如何设置 Java 属性和其他选项. 请查看 How to fix out of memory errors by increasing availabl ...

  8. Map类集合

    集合类                                        Key                            Value                     ...

  9. hdu 5980 Find Small A(水,模拟)

    Find Small A Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  10. 【scala】模式匹配

    Scala的模式匹配是通过match表达式从若干可选项中选择,类似Java中的switch. 例子: val firstArg = if(args.length>0) args(0) else ...