深入分析AIDL原理
在上一篇文章(Service使用方式)中,介绍了Android进程间通信(IPC)的使用,并给出了一个示例。但并没有深入分析aidl是怎样可以做到进程间通信的,它的执行过程是怎样的?
这篇文章来分析IRemoteService.aidl的执行过程,并理解aidl是怎样跨进程通信的。
当我们创建IRemoteService.aidl文件时,IDE会为我们在gen目录中创建相应的文件。
- /** 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)
- 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);。
如:
- //获取状态
 - 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方法
- 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方法,
- 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通信有点复杂,但仔细分析并不是很难
深入分析AIDL原理的更多相关文章
- 深入分析Synchronized原理(阿里面试题)
		
还有一篇 讲解lock的实现原理,参考:解决多线程安全问题-无非两个方法synchronized和lock 具体原理以及如何 获取锁AQS算法 (百度-美团) 记得开始学习Java的时候,一遇到多线程 ...
 - Android探索之旅 | AIDL原理和实例讲解
		
轉載自http://www.jianshu.com/p/ef86f682a8f9 -- 作者 谢恩铭 转载请注明出处 前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Pr ...
 - AIDL原理分析
		
季春初始,天气返暖,新冠渐去,正值学习好时机.在Android系统中,AIDL一直在Framework和应用层上扮演着很重要的角色,今日且将其原理简单分析.(文2020.03.30) 一.开篇介绍 1 ...
 - AIDL原理解析
		
首先为什么需要aidl? 下面是不需要aidl 的binder的IPC通讯过程,表面上结构很简单,但是有个困难就是,客户端和服务端进行通讯,你得先将你的通讯请求转换成序列化的数据,然后调用transa ...
 - AIDL原理之 Framewok层实现
		
AIDLFramework层的架构,如下图: 换而言之,Android就是在传统的C/S架构中加入了一层,实现IPC.图中表明,AIDL类似COM的Proxy/Stub架构.不过是现在android自 ...
 - 深入分析Synchronized原理
		
前言 记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决 ...
 - AIDL通信原理
		
AIDL (Android Interface Definition Language),通过定义通信接口来实现进程间通信.这是Google提供的一种在安卓应用进程间通信的工具.所以要了解AIDL的通 ...
 - 解决多线程安全问题-无非两个方法synchronized和lock 具体原理(百度-美团)
		
还有其他的锁,如果想要了解,参考:JAVA锁机制-可重入锁,可中断锁,公平锁,读写锁,自旋锁, 用synchronized实现ReentrantLock 美团面试题参考:使用synchronized ...
 - 【Java并发专题之三】Java线程互斥、协作原理
		
(I)Java线程互斥原理之synchronized原理 从JDK5引入CAS原子操作,但没有对synchronized关键字做优化,而是增加了J.U.C.concurrent,concurrent包 ...
 
随机推荐
- 杭电1023Train Problem II
			
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1023 题目: Train Problem II Time Limit: 2000/1000 MS (Jav ...
 - 在 Mac OS 上编译 OBS
			
本文转自:在 Mac OS 上编译 OBS | www.samirchen.com 安装环境 第一步,做准备工作,安装编译 OBS 所需要的环境,流程如下: // 给当前用户添加 /usr/local ...
 - 智能指针 auto_ptr、scoped_ptr、shared_ptr、weak_ptr
			
什么是RAII? RAII是Resource Acquisition Is Initialization的简称,是C++语言的一种管理资源.避免泄漏的惯用法. RAII又叫做资源分配即初始化,即:定义 ...
 - 《Python学习手册》(二)
			
<Python学习手册>(二) --类型和运算 数字 十六进制 八进制 二进制 0x 0o 0b hex() oct() bin() >>>int('10',2) 2 & ...
 - C++命名(自定义)
			
1.自定义函数 void GetName(): 2.布尔型变量 BOOL ISOPEN:
 - Git常用分支操作
			
新建分支 git branch branchname 切换到分支dev git checkout branchname 查看所有的分支信息 git branch -a 查看远程分支信息 git bra ...
 - Spring 模块
 - LeetCode—— Invert Binary Tree
			
LeetCode-- Invert Binary Tree Question invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 ...
 - 正则表达式【TLCL】
			
grep[global regular expression print] print lines matching a pattern grep [options] regex [file...] ...
 - 还在纠结注册.com域名还是.cn域名?
			
一.概念 .com域名,国际最广泛流行的通用域名格式.国际化公司都会注册. .com域名:当然也可以选择.net/.org以.com为结尾的国际域名. 例如表示工商企业的 .com. 同时还有 .ne ...