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端服务提供的对应方法。