6.3.2 构造服务的Proxy对象

服务的BinderProxy对象主要与Binder通信相关,需要将其封装到服务接口中供Client端使用。这部分工作由IPowerManager.Stub.asInterface方法完成。

IPowerManager由IPowerManager.aidl文件定义,编译后生成对应的IPowerManager.java文件。asInterface的代码如下:


public static android.os.IPowerManager asInterface(android.os.IBinder obj){

if((obj==null)){

return null;

}

//参数obj为BinderProxy,其queryLocalInterface返回null

android.os.IInterface iin=

(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);

if(((iin!=null)&&(iin instanceof android.os.IPowerManager))){

return((android.os.IPowerManager)iin);

}

return new android.os.IPowerManager.Stub.Proxy(obj);

}


IPowerManager的asInterface方法首先调用queryLocalInterface方法判断接口类型。已知传入的obj为BinderProxy,其queryLocalInterface方法的返回值为null,因此这里将把BinderProxy封装到IPowerManager.Stub.Proxy对象中返回,代码如下:


private static class Proxy implements android.os.IPowerManager{

private android.os.IBinder mRemote;

//将BinderProxy存入成员变量mRemote

Proxy(android.os.IBinder remote){

mRemote=remote;

}

//提供asBinder方法返回BinderProxy

public android.os.IBinder asBinder(){

return mRemote;

}

……

public void goToSleep(long time)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.writeLong(time);

/*通过BinderProxy进行Binder通信,以TRANSACTION_goToSleep

标记要调用服务的哪个方法*/

mRemote.transact(Stub.TRANSACTION_goToSleep, data, reply,0);

reply.readException();

}

……

}


Proxy在成员变量mRemote中存储了BinderProxy对象,而BinderProxy对象内部存储了BpBinder对象,因此Proxy具备与Server端通信的能力。此外,Proxy实现了服务接口IPowerManager, Client端可以通过调用Proxy的方法进而访问Server端服务提供的对应方法。