6.4 Client端调用Java系统服务的方法

6.3 节中分析了服务代理对象的获取过程,该服务对象最终封装到PowerManager中供Client端调用,本节分析调用服务的方法。

以PowerManager的isScreenOn方法为例,代码如下:


public boolean isScreenOn()

{

try{

//mService为IPowerManager.Stub.Proxy

return mService.isScreenOn();

}catch(RemoteException e){

return false;

}

}


可见调用PowerManager的isScreenOn方法是调用IPowerManager.Stub.Proxy的isScreenOn方法,其代码如下:


private static class Proxy implements android.os.IPowerManager{

private android.os.IBinder mRemote;//mRemote存储BinderProxy

……

public boolean isScreenOn()throws android.os.RemoteException{

android.os.Parcel_data=android.os.Parcel.obtain();

android.os.Parcel_reply=android.os.Parcel.obtain();

boolean_result;

try{

_data.writeInterfaceToken(DESCRIPTOR);

//调用BinderProxy的transact方法

mRemote.transact(Stub.TRANSACTION_isScreenOn,_data,_reply,0);

_reply.readException();

_result=(0!=_reply.readInt());//读取返回结果

}finally{

_reply.recycle();

_data.recycle();

}

return_result;

}

……


BinderProxy的transact方法会调用其Native层对等的BpBinder的transact方法,参与进程间通信,这之后的过程与Native层的处理流程是一样的,请参考第5章的内容。

进程间通信的结果是,Binder驱动将Client端的Stub.TRANSACTION_isScreenOn请求转发给BBinder的transact方法,在该方法中调用其onTransact方法处理请求。

onTransact方法由BBinder的子类JavaBBinder(上文中写入ServiceManager的便是该类型的对象)覆盖,其代码如下:


class JavaBBinder:public BBinder

{

virtual status_t onTransact(

uint32_t code, const Parcel&data, Parcel*reply, uint32_t flags=0)

{

JNIEnv*env=javavm_to_jnienv(mVM);

……

//mObject指向Java系统服务,通过JNI函数调用系统服务的execTransact

jboolean res=env->CallBooleanMethod(mObject,

gBinderOffsets.mExecTransact, code,

(int32_t)&data,(int32_t)reply, flags);

jthrowable excep=env->ExceptionOccurred();

if(excep){

……//处理异常

}

……

if(code==SYSPROPS_TRANSACTION){

BBinder:onTransact(code, data, reply, flags);

}

return res!=JNI_FALSE?NO_ERROR:UNKNOWN_TRANSACTION;

}


onTransact方法中需要根据gBinderOffsets.mExecTransact中保存的Binder类(Java层)的Method ID找到并调用mObject对象的execTransact方法。

在本例中,mObject即PowerManagerService,继承自Binder类(Java层),其execTransact方法如下:


public class Binder implements IBinder{

……

private boolean execTransact(int code, int dataObj, int replyObj, int flags){

Parcel data=Parcel.obtain(dataObj);

Parcel reply=Parcel.obtain(replyObj);

boolean res;

try{

res=onTransact(code, data, reply, flags);

}catch(RemoteException e){

reply.setDataPosition(0);

reply.writeException(e);

res=true;

}catch(RuntimeException e){

reply.setDataPosition(0);

reply.writeException(e);

res=true;

}catch(OutOfMemoryError e){

RuntimeException re=new RuntimeException("Out of memory",e);

reply.setDataPosition(0);

reply.writeException(re);

res=true;

}

reply.recycle();

data.recycle();

return res;

}


可见execTransact方法调用onTransact方法,该方法由Binder的子类覆盖。

PowerManager Service中并没有定义onTransact方法,但PowerManagerService继承自IPowerManager.Stub,而IPowerManager.Stub又继承了android.os.Binder, IPowerManager.Stub中覆盖了Binder的onTransact方法,因此这里调用的是PowerManagerService从IPowerManager.Stub中继承的onTransact方法。onTransact方法的代码如下:


public interface IPowerManager extends android.os.IInterface{

public static abstract class Stub extends android.os.Binder implements

android.os.IPowerManager{

public boolean onTransact(int code, android.os.Parcel data,

android.os.Parcel reply, int flags)

throws android.os.RemoteException{

switch(code){

……

//根据Client端发送的code匹配当前对象的相应处理方法

case TRANSACTION_isScreenOn:{

data.enforceInterface(DESCRIPTOR);

//调用子类的isScreenOn实现方法

boolean_result=this.isScreenOn();

reply.writeNoException();

reply.writeInt(((_result)?(1):(0)));

return true;

}

……

}

return super.onTransact(code, data, reply, flags);

}

……


可见,在IPowerManager.Stub的onTransact方法中,会根据Client端传入的请求code,匹配当前对象的对应方法处理请求。

在本例中,对应TRANSACTION_isScreenOn请求码的Server端处理方法是isScreenOn方法。由于PowerManagerService继承自IPowerManager.Stub,因此运行时将调用子类PowerManagerService的isScreenOn方法,该方法代码如下:


public boolean isScreenOn(){

synchronized(mLocks){

return(mPowerState&SCREEN_ON_BIT)!=0;

}

}


在PowerManagerService的isScreenOn方法中,判断其内部成员变量mPowerState的标记位是否设置为SCREEN_ON_BIT,然后返回结果。该结果会被写入reply中,由Binder驱动返回给Client。