深入分析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包 ...
随机推荐
- java字节码理解-入门
前记:作为一名JAVA Developer,每次打开Eclipse,查找一个没有源码的类时,都会看到一个这样的画面: 大意是:这个jar文件,没有附带源码.紧接着后面的就看不懂了,很好奇下面的一部分是 ...
- hadoop21---使用代理修改List,代理流程
package cn.itcast_05_proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...
- Mybatis中trim的使用
trim标记是一个格式化的标记,可以完成set或者是where标记的功能,如下代码: 1. select * from user <trim prefix="WHERE" p ...
- Spring 之通过 XML 装配 bean
1.关于 使用传统标签还是 c- p- 命名空间定义的标签, 我的观点是能用 c- p- 命名空间定义的标签 就不用 传统标签(这样会比较简洁... 2.强依赖使用构造器注入,可选性依赖使用属性注入 ...
- pt-osc测试
pt-osc测试 1.原表必须存在主键 PRIMARY KEY 或者 UNIQUE KEY The new table `darren`.`_t_user_new` does not have a P ...
- html5 canvas js(数字时钟)
<!doctype html> <html> <head> <title>canvas dClock</title> </head ...
- ThinkPHP开发博客系统笔记之二
1. 登陆验证码 当用户登陆的时候我们希望也弹出验证码,有两种方法可以实现:一是再增加一个弹出验证码的dialog,二是和注册共用一个验证码dialog.第一种方法有大量重复代码,所以我们使用第二种方 ...
- idea软件编码已经设置好了为utf-8,但是svn中down下来的文件格式本身不是utf-8的,此时打开后会出现中文乱码解决方法
我是个idea的忠实用户,新公司的项目都是用eclipse做的,通过svn拉下代码后发现,注释的内容里,中文内容都是乱码.问过项目负责人,说可能是GBK编码. 但是,我通过idea的setting设置 ...
- 计算机网络 - IP和端口
计算机网络分层模型 OSI分层模型:物理层.数据链路层.网络层.传输层.会话层.表示层.应用层: TCP/IP分层模型:物理+数据链路层.网络层.传输层.应用层: IP地址 IP地址是一个32位的整数 ...
- Python subplot 绘画
环境 Anaconda3 Python 3.6, Window 64bit 目的 利用 matplotlib 画图模块,汇至子图 # -*- coding: utf-8 -*- import matp ...