- aidl用到的是远程代理模式,为客户端隐藏了IPC的细节。让客户端感觉好像拿到了一个服务器端对象的句柄。
- -------------------------------
- IGreetService.aidl
- -------------------------------
- <ol class="dp-j" start="1"><li class="alt"><span><span class="keyword">package</span><span> com.scott.aidl; </span></span></li><li><span><span class="keyword">import</span><span> com.scott.aidl.Person; </span></span></li><li class="alt"><span> </span></li><li><span><span class="keyword">interface</span><span> IGreetService { </span></span></li><li class="alt"><span> String greet(in Person person); </span></li><li><span>}
- </span></li></ol>
- 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 这些相关的接口和类吧。
转载:http://blog.youkuaiyun.com/safsasasa/article/details/18085871