深入分析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包 ...
随机推荐
- NGUI 3.50 UIButton使用
在NGUI,3.X的版本中,取消了创建UIbutton这个选项,所以我们可以创建uisprite.uilabel等,然后在上面附加uibutton脚本,达到目的,具体步骤 1:在界面上键好2D或3D ...
- React setState更新数组中的某个元素Element item
var items = this.state.items; items[i].status = 'doing'; this.setState({ items: items }); //this.sta ...
- Sybase:SybaseIQ的几个系统过程
Sybase:SybaseIQ的几个系统过程 sp_iqlocks 显示与数据库中 IQ 存储区和目录存储区中的锁有关的信息. 删除锁:drop connection XXX sp_iqwho 显示所 ...
- C++中 int main(int argc, char **argv) 命令行传递参数
C++中,比较常见的是不带参数的主函数int main(),如果使用命令行执行程序,主函数也可以接收预先输入的参数,形式如下. int main(int argc,char **argv) argc: ...
- ELK分布式日志收集搭建和使用
大型系统分布式日志采集系统ELK全框架 SpringBootSecurity1.传统系统日志收集的问题2.Logstash操作工作原理3.分布式日志收集ELK原理4.Elasticsearch+Log ...
- linux tzselect 设置时区
date -R 检查时间 tzselect 按照提示逐步设置 //这里演示的是设置东八区 TZ='Asia/Shanghai'; export TZ 添加到/etc/profile source pr ...
- java基础(4)--运算符及表达式
运算符及表达式 算数运算 加(+) 减(-) 乘(*) 除(/) 取余(%) 自增(++) 自减(- -) 注意点 1. 同种类型参与运算(可能需要自动类型转换),返回同种类型 2. 整数的除法是整 ...
- spring配置mq入门案例
第一步:添加maven配置 <!-- mq --> <dependency> <groupId>org.springframework</groupId> ...
- 深入理解MR1与MR2的执行流程
摘自:Tom White ,<Hadoop.The.Definitive.Guide.3rd.Edition> MR1 MR2
- javascript打开新页面的方法
方案一: A标签: 这里要注意target的设置,_Blank是指新窗口,也可以用js来模拟创建. <a href="http://www.cnblogs.com" targ ...