当创建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. Linux之curl

    简介 curl 是常用的命令行工具,用来请求 Web 服务器.它的名字就是客户端(client)的 URL 工具的意思. 它的功能非常强大,命令行参数多达几十种.如果熟练的话,完全可以取代 Postm ...

  2. day07 类

    一.目录 1.模块 2.包 3.isinstance issubclass type 4.方法和函数 5.反射 6.约束 7.继承 8.特殊成员 9.异常处理 补充知识点 10.hashlib模块 1 ...

  3. win10编译maskrcnn benchmark

    步骤 1. 按照官网的Option1安装步骤安装 https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/INSTALL. ...

  4. 4.3. Scrapy Shell

    Scrapy Shell:模拟scrapy去发送请求 Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方 ...

  5. 第七章 路由 77 路由-使用children属性实现路由嵌套

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

  6. 第七章 路由 71 路由-router-link的使用

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

  7. innerHTML和innerText的使用和区别

    document对象中有innerHTML.innerText这两个属性,都是获取document对象文本内容,但使用起来还是有区别的: 1) innerHTML设置或获取标签所包含的HTML+文本信 ...

  8. 【JS】类型检测

    本文首发于我的个人博客 : http://cherryblog.site/ 前言 js 中的类型检测也是很重要的一部分,所以说这篇文章我们就来讲一下怎么对 JavaScript 中的基本数据类型进行检 ...

  9. vue插件——滚动监听 vue-scrollwatch

    造轮子的目的: 做项目的时候需要一个滚动监听的功能,html结构已经都写好了,不想使用vue组件的方式来写,因为不想改造html结构,于是花了几个小时做了一个简单的,使用vue指令方式来做的,项目上够 ...

  10. Object-C(自学1)

    ----- 需求索要 自学了下 OBJECt-C  ----- 就基础部分一些 和操作 command + R 运行command +B 只编译.m文件 NSlog() = printfNSLog 是 ...