深入分析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包 ...
随机推荐
- centos7 firewall开放查看关闭端口
查看所有打开的端口: firewall-cmd --zone=public --list-ports 添加 firewall-cmd --zone=public --add-port=80/tcp - ...
- IDEA MAVEN Project 显示问题
今天正常打开idea,却发现maven窗口找不到了:试了这些方法 首先idea自带了maven控件,不像Eclipse还需要下载控件,如果你以前有maven在右边,出于某种原因,消失找不到 了,你可以 ...
- Android Camera 通过V4L2与kernel driver的完整交互过程
http://blog.chinaunix.net/uid-26215986-id-3552456.html 原文地址:Android Camera 通过V4L2与kernel driver的完整交互 ...
- jQuery图片分组切换焦点图
在线演示 本地下载
- MapReduce:输入是两个文件,file1代表工厂表,包含工厂名列和地址编号列;file2代表地址表,包含地址名列和地址编号列。要求从输入数据中找出工厂名和地址名的对应关系,输出"工厂名----地址名"表
文件如下: file1: Beijing Red Star Shenzhen Thunder Guangzhou Honda Beijing Rising Guangzhou Development ...
- Spring_自动装配
Beans-autowire.xml <?xml version="1.0" encoding="UTF-8"?><beans xmlns=& ...
- fabric网关模式文件上传与执行
- php数组元素去空,测试奇数偶数
<?php//返回奇数 function test_odd($var) { return($var & 1); } $a1=array("a","b&quo ...
- MySQL 触发器简单实例 - 转载
MySQL 触发器简单实例 触发器:可以更新,删除,插入触发器,不同种类的触发器可以存在于同一个表,但同种类的不能有多个.一个更新.一个删除是可以共存的. ~~语法~~ CREATE TRIGGER ...
- Java 关于assert
昨天在看NIO源码的时候,看到这样一句,顿时懵逼了 : assert (i >= 0); assert关键词我是有映像的, 中文叫断言.但是从来没有去了解过它的功能, 今天在感冒中抽出时间, 把 ...