aidl用到的是远程代理模式,为客户端隐藏了IPC的细节。让客户端感觉好像拿到了一个服务器端对象的句柄。
-------------------------------
IGreetService.aidl
-------------------------------
- package com.scott.aidl;
- import com.scott.aidl.Person;
-
- interface IGreetService {
- String greet(in Person person);
- }
这个aidl经过编译之后得到IGreetServcie.java
package com.scott.aidl;
public interface IGreetService extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.scott.aidl.IGreetService {
private static final java.lang.String DESCRIPTOR = "com.scott.aidl.IGreetService";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.scott.aidl.IGreetService
* interface, generating a proxy if needed.
*/
public static com.scott.aidl.IGreetService 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.scott.aidl.IGreetService))) {
return ((com.scott.aidl.IGreetService) iin);
}
return new com.scott.aidl.IGreetService.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_greet: {
data.enforceInterface(DESCRIPTOR);
com.scott.aidl.Person _arg0;
if ((0 != data.readInt())) {
_arg0 = com.scott.aidl.Person.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
java.lang.String _result = this.greet(_arg0);
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.scott.aidl.IGreetService {
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 java.lang.String greet(com.scott.aidl.Person person) 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 ((person != null)) {
_data.writeInt(1);
person.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_greet, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_greet = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String greet(com.scott.aidl.Person person) throws android.os.RemoteException;
}
这里面一共定义了三个class.
首先看第一个Interface的申明:
public interface IGreetService extends android.os.IInterface {
这个Interface继承了 android.os.IInterface
1 /*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package android.os;
18
19 /**
20 * Base class for Binder interfaces. When defining a new interface,
21 * you must derive it from IInterface.
22 */
23 public interface IInterface
24 {
25 /**
26 * Retrieve the Binder object associated with this interface.
27 * You must use this instead of a plain cast, so that proxy objects
28 * can return the correct result.
29 */
30 public IBinder asBinder();
31 }
就是一个类型转换,注释里面说是要用这个函数的转换而不是强制类型转换,从而让代理对象可以返回一个正确的值。那就看一下代理对象是如何实现这个函数的。
于是第二个类出现了
private static class Proxy implements com.scott.aidl.IGreetService {
这个类实现了上述接口,并且是一个私有的静态内部类。他实现IInterface中的asBinder方法如下:
public android.os.IBinder asBinder() {
return mRemote;
}
mRemote是从哪儿来的?
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
原理是从构造函数传过来的。那代理对象是在哪里构造的?
public static com.scott.aidl.IGreetService 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.scott.aidl.IGreetService))) {
return ((com.scott.aidl.IGreetService) iin);
}
return new com.scott.aidl.IGreetService.Stub.Proxy(obj);
}
这是在另外一个内部类里面的,这个类的声明如下:
public static abstract class Stub extends android.os.Binder implements com.scott.aidl.IGreetService {
这个类继承了Binder,并且实现了之前的那个人service,跟上面那个类一样的。之前那个类是私有的,这个是共有的而且还是抽象的。
刚好这里面有个函数asInterface。这说明Binder需要把自己转化成一个Interface给别人用。而Interface需要把自己转化为Binder给别人用。真是一对好机油啊。
因为客户端需要的是一个Interface的句柄,所以这里提供了这个函数。客户端是这样调用的
IGreetService remoteService = IGreetService.Stub.asInterface(binder); 这个binder是系统回调 service的 onConnection的时候传过来的。
这段代码大概意思就是说如果service是一个本地对象就可以直接拿到service对象的句柄,否则我们就通过remote proxy的方式拿到一个代理对象。由这个代理对象在背后
默默的为我们工作,默默的处理进程间通讯的问题。
这里面比较绕的是内部类跟外部类的关系比较复杂。不止是内外的关系,内部类又继承了外部类,而且继承的层次还不只一层,有两层嵌套。而且还巧妙的运用了proxy的
设计模式。有趣的是这段代码是自动生成的,我们只需要定义Aidl文件,编译器会自动帮我们生成这段代码。值得看一下!后面再看一下IBinder Binder, Service ServiceConnection 这些相关的接口和类吧。
参考了android源码,和一篇博客,附上地址http://blog.csdn.net/liuhe688/article/details/6409708