当创建AIDL文件并Clean Project 代码后,会生成相应的Java文件:

先来一段伪代码:类整体结构

/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\AndroidProject\\AIDLServerDemo\\app\\src\\main\\aidl\\cn\\zzw\\aidl\\IPerson.aidl
*/
package cn.zzw.aidl;
// Declare any non-default types here with import statements

public interface IPerson extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements cn.zzw.aidl.IPerson //1
{
...
}

public java.lang.String sayHello(cn.zzw.aidl.PersonInfo personInfo) throws android.os.RemoteException; //2

public int sumnNum(int num1, int num2) throws android.os.RemoteException; //3
}
注释2 和注释3 就是我们在.aidl 中定义的方法。

注释1 是一个静态的抽象类,并且继承了Binder类。Binder是Android中实现IPC方式。AIDL就是利用Binder来实现的。

这里就不对于Binder进行解释,后面会对Binder的源码进行解读,再记录一篇关于Binder的原理。

看看Stub这个类:

public static abstract class Stub extends android.os.Binder implements cn.zzw.aidl.IPerson {
private static final java.lang.String DESCRIPTOR = "cn.zzw.aidl.IPerson";

/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}

/**
* Cast an IBinder object into an cn.zzw.aidl.IPerson interface,
* generating a proxy if needed.
*/
public static cn.zzw.aidl.IPerson asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof cn.zzw.aidl.IPerson))) {
return ((cn.zzw.aidl.IPerson) iin);
}
return new cn.zzw.aidl.IPerson.Stub.Proxy(obj);
}

@Override
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 {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_sayHello: {
data.enforceInterface(descriptor);
cn.zzw.aidl.PersonInfo _arg0;
if ((0 != data.readInt())) {
_arg0 = cn.zzw.aidl.PersonInfo.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
java.lang.String _result = this.sayHello(_arg0);
reply.writeNoException();
reply.writeString(_result);
return true;
}
case TRANSACTION_sumnNum: {
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.sumnNum(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}

private static class Proxy implements cn.zzw.aidl.IPerson {
private android.os.IBinder mRemote;

Proxy(android.os.IBinder remote) {
mRemote = remote;
}

@Override
public android.os.IBinder asBinder() {
return mRemote;
}

public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}

@Override
public java.lang.String sayHello(cn.zzw.aidl.PersonInfo personInfo) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((personInfo != null)) {
_data.writeInt(1);
personInfo.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

@Override
public int sumnNum(int num1, int num2) 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.writeInt(num1);
_data.writeInt(num2);
mRemote.transact(Stub.TRANSACTION_sumnNum, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}

static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_sumnNum = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
Stub类的类结构如下:

下面两个int常量是用来标识我们在接口中定义的方法的:

static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_sumnNum = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
DESCRIPTOR 常量是Binder的唯一标识。

private static final java.lang.String DESCRIPTOR = "cn.zzw.aidl.IPerson";
 asInterface 方法非常熟悉,上面客户端才用到的,用于将服务端的Binder对象转换为客户端所需要的接口对象。该过程区分进程,如果进程一样,就返回服务端Stub对象本身,否则就返回封装后的Stub.Proxy对象。

public static cn.zzw.aidl.IPerson asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof cn.zzw.aidl.IPerson))) {
return ((cn.zzw.aidl.IPerson) iin);
}
return new cn.zzw.aidl.IPerson.Stub.Proxy(obj);
}
onTransact  方法是实现 Binder 类后重写的方法。这是运行在服务端的Binder线程中的,当客户端发起远程请求后,在底层的方法就会触发此方法。

AIDL 的工作原理的更多相关文章

  1. 初涉IPC,了解AIDL的工作原理及使用方法

    初涉IPC,了解AIDL的工作原理及使用方法 今天来讲讲AIDL,这个神秘的AIDL,也是最近在学习的,看了某课大神的讲解写下的blog,希望结合自己的看法给各位同价通俗易懂的讲解 官方文档:http ...

  2. 初涉IPC,了解AIDL的工作原理及用法

    初涉IPC,了解AIDL的工作原理及用法 今天来讲讲AIDL.这个神奇的AIDL,也是近期在学习的,看了某课大神的解说写下的blog,希望结合自己的看法给各位同价通俗易懂的解说 官方文档:http:/ ...

  3. 浅析AIDL的使用和工作原理

    AIDL是一种接口定义语言,用于生成可在Android设备上两个进程之间进行进程间通信(IPC)的代码. AIDL的使用 新建一个aidl文件,定义进程间通信的接口 // IStudentManage ...

  4. 2019 Android 高级面试题总结 从java语言到AIDL使用与原理

    说下你所知道的设计模式与使用场景 a.建造者模式: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 使用场景比如最常见的AlertDialog,拿我们开发过程中举例,比如C ...

  5. 菜鸟学Struts2——Struts工作原理

    在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...

  6. 【夯实Nginx基础】Nginx工作原理和优化、漏洞

    本文地址 原文地址 本文提纲: 1.  Nginx的模块与工作原理    2.  Nginx的进程模型    3 . NginxFastCGI运行原理        3.1 什么是 FastCGI   ...

  7. HashMap的工作原理

    HashMap的工作原理   HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间 ...

  8. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    RAC 工作原理和相关组件(三) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  9. ThreadLocal 工作原理、部分源码分析

    1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...

随机推荐

  1. TCP/IP协议栈各个层次及分别的功能

    网络接口层:这是协议栈的最低层,对应OSI的物理层和数据链路层,主要完成数据帧的实际发送和接收.网络层:处理分组在网络中的活动,例如路由选择和转发等,这一层主要包括IP协议.ARP.ICMP协议等.传 ...

  2. httpclient 上传附件实例

    httpclient 单附件上传实例  (扩展多附件上传实例,点我) /** * 上传附件 * @param host * @param uri * @param filePath 文件路径 * @p ...

  3. jmeter压测实践

    技巧一:命令行执行 命令执行:指定参数,报告的存储位置 jmeter -n -t baidu_requests_results.jmx -r -l baidu_requests_results.jtl ...

  4. vue学习(2)-过滤器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. OGG学习笔记03

    OGG学习笔记03-单向复制简单故障处理 环境:参考:OGG学习笔记02-单向复制配置实例实验目的:了解OGG简单故障的基本处理思路. 1. 故障现象故障现象:启动OGG源端的extract进程,da ...

  6. go语言入门(3)运算符及流程控制

    1,运算符 算数运算符:+   -   *   /   %   ++   -- 关系运算符:==    !=    <    >    <=    >== 逻辑运算符:按位与 ...

  7. JavaMaven【五、Maven集成Eclipse使用】

    创建Maven项目 右键->new->other(Ctrl+n)->Maven Project->quickStart(catalog) 执行指令 右键->Run As- ...

  8. Centos7查不出ip地址

    今天遇到了这个问题,解决后记录一下: //输入查询命令 ifconfig或者ip addr 如图,是显示不出信息的 找到ens33的配置文件,输入命令 vi /etc/sysconfig/networ ...

  9. Win10系统的开机启动项如何去关闭?

    我们在使用电脑时会安装许多的应用程序,而有些应用程序会默认在电脑开机时自行启动,不仅影响开机速度,还会在开机后占用电脑内存资源. 那么在Win10系统中,我们该如何查看有哪些开机启动项呢?我们又该怎么 ...

  10. 【wifi移植 1】 ap6210 wifi模块移植

    1. 编译wifi相关功能为模块,生成bcmdhd.ko:由bcmdhd.ko的模块信息可知,该模块依赖于cfg80211.ko和rfkill.ko. 2. 写脚本,开机自动加载wifi模块. 3. ...