AIDL机制解析

关于AIDL的使用,已经在之前的博客Android AIDL的基本用法

里介绍过,这次主要通过剖析AIDL生成的java文件来讲解AIDL机制。用的还是之前博客的例子,它在build目录下生成的 IMyAidlInterface.java 文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\AndroidStudioProjects\\AIDLServer\\app\\src\\main\\aidl\\cn\\qiracle\\aidlserver\\IMyAidlInterface.aidl
*/

package cn.qiracle.aidlserver;
// Declare any non-default types here with import statements

public interface IMyAidlInterface extends android.os.IInterface
{

/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements cn.qiracle.aidlserver.IMyAidlInterface
{

private static final java.lang.String DESCRIPTOR = "cn.qiracle.aidlserver.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{

this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an cn.qiracle.aidlserver.IMyAidlInterface interface,
* generating a proxy if needed.
*/

public static cn.qiracle.aidlserver.IMyAidlInterface asInterface(android.os.IBinder obj)
{

if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof cn.qiracle.aidlserver.IMyAidlInterface))) {
return ((cn.qiracle.aidlserver.IMyAidlInterface)iin);
}
return new cn.qiracle.aidlserver.IMyAidlInterface.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
{

switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_print:
{
data.enforceInterface(DESCRIPTOR);
this.print();
reply.writeNoException();
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements cn.qiracle.aidlserver.IMyAidlInterface
{

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 void print() 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_print, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public int add(int a, int b) 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(a);
_data.writeInt(b);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void print() throws android.os.RemoteException;
public int add(int a, int b) throws android.os.RemoteException;
}

结合上面的代码,我们一起看下:

Stub 是aidl接口的静态抽象内部类,它继承于binder同时实现了aidl的接口,因为是抽象类,具体实现还是在server端service里创建一个binder的内部类继承这个Stub实现的

Proxy 是Stub的静态内部类,它也实现了aidl的接口

调用流程
Client 在 bindService 之后,在 onServiceConnected 的回调里,拿到 IBinder 对象,通过 asInterface 方法,拿到proxy对象,前面说的,Proxy是Stub的静态内部类,它也实现了aidl的接口,所以通过这个proxy对象,我们就可以调 aidl 接口里定义的方法。这个 proxy 是个代理,它对 aidl 接口的具体实现是把要调的方法名,参数通过 remote. transact 传给服务端,这里的 remote 就是前面的 binder 对象,binder 通过 IPC 机制把要调用的方法名,方法参数传给了Server端.

这时来到 Server 端,通过 client 端的 remote.transact 方法,会回调 Server 端的 onTransact 方法,onTransact 方法里有个 switch-case,根据回调里的code值,也就是方法名,找到对应的方法去执行,具体执行的方法就是service里创建的内部binder实现类里实现的方法。

总结一下,从这个过程也可以看出,AIDL 用的是代理模式,Binder机制。所谓调用Server方法其实是通过代理对象把要调用的方法名,方法参数通过binder机制传给了Server端,server端再自己调用的一个过程

文章目录
|