[TOC]

概述

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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

package cn.frewen.wang.carinfo;

/**
* AIDL的接口继承了IInterface这个接口,同时它自己也还是个接口
* 所有可以在Binder中传输的接口都需要继承IInterface接口。
*/
public interface ICarInfo extends android.os.IInterface {
/**
* 内部类Stub,这个Stub就是一个Binder类
* 客户端和服务端都位于同一个进程时,方法调用不会走跨进程的transact过程
* 我们可以在服务端来进行进行实现Stub这个Binder的的接口实现。
* 一般都是实现一个匿名的ICarInfo.Stub 然后实现这个接口里面定义的方法
**/
public static abstract class Stub extends android.os.Binder implements cn.sh.changxing.carinfo.ICarInfo {
private static final java.lang.String DESCRIPTOR = "wang.frewen.carinfo.ICarInfo";
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* 用于将服务端的Binder对象转换成客户端所需的AIDL接口类型的对象,
* 这种转换过程是区分进程的,
* 如果客户端和服务端位于同一进程 那么此方法返回的就是服务端的Stub对象本身
* 否则返回的是系统封装后的Stub.proxy对象。也就是Binder对象的客户端代理对象。
*/
public static frewen.wang.carinfo.ICarInfo asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
// 这个asInterface()方法的逻辑其实和C++中的asInterface()函数的逻辑是一样的

android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof cn.sh.changxing.carinfo.ICarInfo))) {
return ((cn.sh.changxing.carinfo.ICarInfo) iin);
}
// 返回Stub的内部代理类
return new cn.sh.changxing.carinfo.ICarInfo.Stub.Proxy(obj);
}

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

/**
* 这个方法运行在服务端中的Binder线程池中
* 当客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法来处理
* 该方法的原型为public BooleanonTransact (int code, android.os.Parcel data, android.os.Parcel reply, intflags)
* 服务端通过code可以确定客户端所请求的目标方法是什么,接着从data中取出目标方法所需的参数(如果目标方法有参数的话),
* 然后执行目标方法。当目标方法执行完毕后,就向reply中写入返回值(如果目标方法有返回值的话),onTransact方法的执行过程就是这样的。
* 需要注意的是,如果此方法返回false,那么客户端的请求会失败,因此我们可以利用这个特性来做权限验证,
* 毕竟我们也不希望随便一个进程都能远程调用我们的服务。
* @param code
* @param data
* @param reply
* @param flags
* @return
* @throws android.os.RemoteException
*/
@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_getCarSpeed: {
// 这个方法是进行描述符的校验
data.enforceInterface(DESCRIPTOR);
// 获取getCarSpeed的方法的结果
int _result = this.getCarSpeed();
reply.writeNoException();
// 然后将加过写入reply
reply.writeInt(_result);
return true;
}
case TRANSACTION_getCarGear: {
data.enforceInterface(DESCRIPTOR);
int _result = this.getCarGear();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_getCarDoorLock: {
data.enforceInterface(DESCRIPTOR);
int _result = this.getCarDoorLock();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_registerCallBack: {
data.enforceInterface(DESCRIPTOR);
cn.sh.changxing.carinfo.ICarInfoCallback _arg0;
_arg0 = cn.sh.changxing.carinfo.ICarInfoCallback.Stub.asInterface(data.readStrongBinder());
this.registerCallBack(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_unregisterCallBack: {
data.enforceInterface(DESCRIPTOR);
cn.sh.changxing.carinfo.ICarInfoCallback _arg0;
_arg0 = cn.sh.changxing.carinfo.ICarInfoCallback.Stub.asInterface(data.readStrongBinder());
this.unregisterCallBack(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}

private static class Proxy implements cn.sh.changxing.carinfo.ICarInfo {
private android.os.IBinder mRemote;

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

/**
* asBinder此方法返回当前的Binder对象
* 如果是跨进程的Binder对象。则返回的就是android.os.IBinder mRemote
* 也就是AIDL跨进程调用回调过来的Binder对象
* @return
*/
@Override
public android.os.IBinder asBinder() {
return mRemote;
}

/**
* Binder的唯一标识,一般用当前Binder的类的全路径名
* @return
*/
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}

/**
* 这个方法是运行在客户端的的
* @return
* @throws android.os.RemoteException
*/
@Override
public int getCarSpeed() throws android.os.RemoteException {
// 创建该方法所需要的输入型Parcel对象_data、输出型Parcel对象_reply和返回值对象
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
// 写入我们调用的Binder接口的Binder对象描述符
_data.writeInterfaceToken(DESCRIPTOR);
// 调用transact方法来发起RPC(远程过程调用)请求,同时当前线程挂起;
// 然后服务端的onTransact方法会被调用,直到RPC过程返回后,当前线程继续执行,
// 并从_reply中取出RPC过程的返回结果;最后返回_reply中的数据。
mRemote.transact(Stub.TRANSACTION_getCarSpeed, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

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

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

@Override
public void registerCallBack(cn.sh.changxing.carinfo.ICarInfoCallback cb) 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((((cb != null)) ? (cb.asBinder()) : (null)));
mRemote.transact(Stub.TRANSACTION_registerCallBack, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}

@Override
public void unregisterCallBack(cn.sh.changxing.carinfo.ICarInfoCallback cb) 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((((cb != null)) ? (cb.asBinder()) : (null)));
mRemote.transact(Stub.TRANSACTION_unregisterCallBack, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}

static final int TRANSACTION_getCarSpeed = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getCarGear = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_getCarDoorLock = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_registerCallBack = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_unregisterCallBack = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
}

public int getCarSpeed() throws android.os.RemoteException;

public int getCarGear() throws android.os.RemoteException;

public int getCarDoorLock() throws android.os.RemoteException;

public void registerCallBack(cn.sh.changxing.carinfo.ICarInfoCallback cb) throws android.os.RemoteException;

public void unregisterCallBack(cn.sh.changxing.carinfo.ICarInfoCallback cb) throws android.os.RemoteException;
}