4、Service代理对象方法的过程;
@ServiceManager.java(google-code\frameworks\base\core\java\android\os\ServiceManager.java) public final class ServiceManager { private static IServiceManager getIServiceManager() { } public static IBinder getService(String name) { } public static void addService(String name, IBinder service) { } public static void addService(String name, IBinder service, boolean allowIsolated) { } public static IBinder checkService(String name) { } public static String[] listServices() throws RemoteException { } public static void initServiceCache(Map<String, IBinder> cache) { } }
这个类比较简单,而且我们看到,ServiceManager没有继承任何的类,那么他是如何实现“管理员”的角色呢?
@SystemServer.java(google-code\frameworks\base\services\java\com\android\server\SystemServer.java) class ServerThread extends Thread { @Override public void run() { try { statusBar = new StatusBarManagerService(context, wm); //调用ServiceManager注册服务 ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar); } catch (Throwable e) { reportWtf("starting StatusBarManagerService", e); } } }我们看到,作为一个Service,可以通过调用ServiceManager的addService()方法注册自己。注册的时候传递了两个参数,Context.STATUS_BAR_SERVICE作为该Service的name,StatusBarManagerService作为该Service的BBinder子类对象,一起传递给了ServiceManager。这样的形式正符合Native层ServiceManager中Service的注册方式。
@ServiceManager.java public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } }在addService()内部,把addService()的请求转发给了getIServiceManager()得到的对象。
private static IServiceManager sServiceManager; private static IServiceManager getIServiceManager() { if (sServiceManager != null) { //单例模式 return sServiceManager; } //得到ServiceManager的Java层代理对象 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }这里看到,通过getIServiceManager()可以得到一个IServiceManager类型的sServiceManager对象, 那么这个对象究竟是什么属性的呢?
@BinderInternal.java(google-code\frameworks\base\core\java\com\android\internal\os\BinderInternal.java) public static final native IBinder getContextObject();他的声明方式说明这个方法是在Native中被实现的,那么他具体定义是在哪里呢?
@AndroidRuntime.cpp(google-code\frameworks\base\core\jni\AndroidRuntime.cpp) void AndroidRuntime::start(const char* className, const char* options) { //开始注册方法 if (startReg(env) < 0) { return; } }在虚拟机启动时,将会通过startReg()方法去注册jni:
int AndroidRuntime::startReg(JNIEnv* env) { //注册gRegJNI列表中的jni方法 if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { env->PopLocalFrame(NULL); return -1; } return 0; }在上面的startReg()中将会遍历gRegJNI列表并注册,我们来看需要注册的列表内容:
static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_Binder), };其中就包括了register_android_os_Binder():
@android_util_Binder.cpp(google-code\frameworks\base\core\jni\android_util_Binder.cpp) int register_android_os_Binder(JNIEnv* env) { //注册BinderInternal中的jni if (int_register_android_os_BinderInternal(env) < 0) return -1; return 0; }在register_android_os_Binder中对BinderInternal中的jni进行注册:
static int int_register_android_os_BinderInternal(JNIEnv* env) { jclass clazz; //根据路径找到类 clazz = env->FindClass(kBinderInternalPathName); gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderInternalOffsets.mForceGc = env->GetStaticMethodID(clazz, "forceBinderGc", "()V"); //注册gBinderInternalMethods中的jni return AndroidRuntime::registerNativeMethods( env, kBinderInternalPathName, gBinderInternalMethods, NELEM(gBinderInternalMethods)); }我们再来看gBinderInternalMethods中定义的方法:
static const JNINativeMethod gBinderInternalMethods[] = { { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject }, { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool }, { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling }, { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc } };这个数组中就定义了getContextObject方法所对应的jni实现,其实就是android_os_BinderInternal_getContextObject(),也就是说,getContextObject()将会调用到android_os_BinderInternal_getContextObject(),我们看一下这个方法的定义:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { //得到BpBinder(0)对象 sp<IBinder> b = ProcessState::self()->getContextObject(NULL); //将BpBinder对象转换为Java对象 return javaObjectForIBinder(env, b); }在这个方法中,完成了两步重要的操作:
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { //单例模式 return sServiceManager; } //得到ServiceManager的Java层代理对象 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }经过前面2.1的分析,我们了解了通过BinderInternal.getContextObject()可以得到BpBinder(0)的Java层代理对象,接下来就需要 调用ServiceManagerNative的asInterface()方法将该对象转换为Java层可用的ServiceManager代理对象。
private static IServiceManager getIServiceManager() { //得到ServiceManager的Java层代理对象 sServiceManager = ServiceManagerNative.asInterface(BpBinder(0)); return sServiceManager; }我们接下来看ServiceManagerNative的asInterface()的过程。
@ServiceManagerNative.java(google-code\frameworks\base\core\java\android\os\ServiceManagerNative.java) static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } //查询本地缓存 IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //创建代理对象 return new ServiceManagerProxy(obj); }我们看到,通过asInterface()的转换, 我们用BpBinder对象生成了ServiceManagerProxy对象。
class ServiceManagerProxy implements IServiceManager {}从继承关系上来看, ServiceManagerProxy实现了IServiceManager中定义的接口。
public ServiceManagerProxy(IBinder remote) { mRemote = remote; }这里的构造函数中,把BpBinder(0)保存在了mRemote变量中。
class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy(IBinder remote) { } public IBinder asBinder() { } public IBinder getService(String name) throws RemoteException { } public IBinder checkService(String name) throws RemoteException { } public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { } public String[] listServices() throws RemoteException { } public void setPermissionController(IPermissionController controller) throws RemoteException { } }我们看到,ServiceManagerProxy确实实现了IServiceManager中的方法,提供了add、get、check、list等功能。
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }在addService的时候,将当前Service的name和service对象封装到Parcel类型的data中,然后调用mRemote对象的transact()方法发送出去,并标记当前的操作是“ADD_SERVICE_TRANSACTION”,还记得我们在分析ServiceManagerProxy的构造函数时传递的参数其实是BpBinder对象,那么这里的transact()就会调用到BpBinder中:
@BpBinder.cpp status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) { //进入IPCThreadState继续调用 status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT; }到这里,就进入了Native层Binder的使用了,接下来就是经过IPCThreadState把请求发送到Binder驱动,然后在ServiceManager的进程中检测到请求并处理,这个过程在Native层分析时详细介绍过,这里就不再分析了。
下面用一张图来示意Java层ServiceManager和Native层ServiceManager的关系:
@IccPhoneBookInterfaceManagerProxy.java(google-code\frameworks\opt\telephony\src\java\com\android\Internal\telephony\) public IccPhoneBookInterfaceManagerProxy(IccPhoneBookInterfaceManager iccPhoneBookInterfaceManager) { mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager; if(ServiceManager.getService("simphonebook") == null) { ServiceManager.addService("simphonebook", this); } }这就是simphonebook的注册过程,看似简单,但是有个疑问,我们知道,在addService()的操作时,必须传递2个参数:name+IBinder子类对象,但是这里的this所指的IccPhoneBookInterfaceManagerProxy对象,是IBinder子类的对象吗?
public class IccPhoneBookInterfaceManagerProxy extends IIccPhoneBook.Stub {}我们看到,他继承了一个IIccPhoneBook.Stub的父类,这个父类是什么属性呢?他和BBinder的子类吗?
@IMyService.aidl package com.pack; interface IMyService{ String getValue(); }这个文件中只有一个方法getValue(),然后我们来看系统为其生成的Java文件:
@IMyService.java package com.pack; public interface IMyService extends android.os.IInterface { //Stub继承自Binder,并且实现了IMyService的接口 public static abstract class Stub extends android.os.Binder implements com.pack.IMyService { } }从生成的Java文件可以看出,IMyService.Stub是android.os.Binder的子类,而android.os.Binder又是IBinder的子类:
@Binder.java(google-code\frameworks\base\core\java\android\os\) public class Binder implements IBinder{}由此我们推断,IccPhoneBookInterfaceManagerProxy的父类IIccPhoneBook.Stub也是IBinder的子类。下面我们来看这个Service的使用方法。
@IccProvider.java(google-code\frameworks\opt\telephony\src\java\com\android\internal\telephony\) private boolean addIccRecordToEf(int efType, String name, String number, String[] emails, String pin2) { boolean success = false; try { //得到simphonebook的Service IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(ServiceManager.getService("simphonebook")); if (iccIpb != null) { //添加SIM卡联系人 success = iccIpb.updateAdnRecordsInEfBySearch(efType, "", "", name, number, pin2); } } catch (RemoteException ex) { } catch (SecurityException ex) { } return success; }上面这个方法的作用就是向SIM卡中添加联系人的操作,在这个操作过程中, 先要通过Java层的ServiceManager得到"simphonebook"的Service,然后通过asInterface()方法将得到的Service对象转换成客户端可以直接调用的代理对象,然后再调用该代理对象的的updateAdnRecordsInEfBySearch()方法。
@ServiceManager.java public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { //调用的是getIServiceManager()对象的getService()方法 return getIServiceManager().getService(name); } } catch (RemoteException e) { } return null; } private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } //通过getIServiceManager得到的其实是ServiceManager的Java层代理对象 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }在2.2节中我们介绍过,在getIServiceManager()中得到的对象,就是ServiceManager在Java层的代理对象:ServiceManagerProxy。
@ServiceManagerNative.java class ServiceManagerProxy implements IServiceManager { //ServiceManagerProxy的getService()方法 public IBinder getService(String name) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); //这里的mRemote就是ServiceManager的BpBinder对象 mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; } }我们看到,ServiceManagerProxy将会把我们的请求(getService)转交给Native层的ServiceManager的BpBinder对象,而在《Binder源码分析之Native层》一文中我们分析过,Native层的ServiceManager得到这种请求后,将会把目标Service的BpBinder对象返回给客户端。
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(ServiceManager.getService("simphonebook"));上面的代码相当于:
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(BpBinder("simphonebook"));接下来的分析,我们就要继续看生成的IIccPhoneBook.java文件了,我们还是借助刚刚生成的IMyService.java文件来看其asInterface()接口:
@IMyService.java public interface IMyService extends android.os.IInterface { public static abstract class Stub extends android.os.Binder implements com.pack.IMyService { public static com.pack.IMyService asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.pack.IMyService))) { return ((com.pack.IMyService) iin); } //通过asInterface()得到的是Proxy对象,并且把BpBinder对象作为参数传递进去 return new com.pack.IMyService.Stub.Proxy(obj); } //代理类Proxy继承自IMyService.aidl,需要实现里面的所有接口 private static class Proxy implements com.pack.IMyService { private android.os.IBinder mRemote; //保存得到的BpBinder对象 Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public java.lang.String getValue() throws android.os.RemoteException { } } static final int TRANSACTION_getValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public java.lang.String getValue() throws android.os.RemoteException; }原来,我们通过IMyService.Stub.asInterface()得到的是一个Proxy的代理对象,这个对象是IMyService.Stub的内部类,也是IMyService的子类,需要实现IMyService.aidl文件中定义的方法。
private static class Proxy implements com.pack.IMyService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public java.lang.String getValue() throws android.os.RemoteException { //准备Parcel数据 android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); //调用mRemote的transact()方法发送数据,并且标记当前调用的方法为getValue mRemote.transact(Stub.TRANSACTION_getValue, _data, _reply, 0); //提取服务端的返回值 _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } }在Proxy的getValue()方法中,将客户端的请求封装为Parcel类型的数据通过mRemote变量发送出去,而且在发送时标记了当前的命令是TRANSACTION_getValue,也就是调用getValue方法,那么这里的mRemote对象是什么呢?
@BpBinder.cpp status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) { //向Service发送请求 status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT; }接下来就是Native层的流程了。看来Proxy代理的作用就是在客户端调用各种方法时,将方法编号(TRANSACTION_getValue)后通过目标Service的BpBinder对象向Native层的Binder机制发送(transact)请求,同时准备在reply中接收服务端的返回值。
@Binder.cpp status_t BBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t err = NO_ERROR; switch (code) { case PING_TRANSACTION: reply->writeInt32(pingBinder()); break; default: //调用BBinder的子类去处理当前请求 err = onTransact(code, data, reply, flags); break; } return err; }我们看到,在BBinder的transact()方法中,将会调用Service的onTransact()的方法,由于当前的IMyService就是BBinder的子类,因此这里的onTransact()方法将会进入到IMyService的内部,也就是:
public interface IMyService extends android.os.IInterface { public static abstract class Stub extends android.os.Binder implements com.pack.IMyService { 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_getValue: { //客户端发起的getValue()的请求 data.enforceInterface(DESCRIPTOR); //继续调用子类的getValue()方法 java.lang.String _result = this.getValue(); reply.writeNoException(); reply.writeString(_result); return true; } } return super.onTransact(code, data, reply, flags); } static final int TRANSACTION_getValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public java.lang.String getValue() throws android.os.RemoteException; }我们看到在onTransact()中将会继续调用子类的getValue()方法,而这里的IMyService.Stub的子类,当然就是客户端本身了。如果结合IIccPhoneBook的服务端来看,当在IIccPhoneBook.Stub中调用其onTransact()方法时,就会在相应的TRANSACTION_xxx分支中调用到IccPhoneBookInterfaceManagerProxy.java中的各个方法,这样也就完成了从客户端到服务端的调用过程。
public java.lang.String getValue() 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); //经历了一次漫长的跨进程调用过程 mRemote.transact(Stub.TRANSACTION_getValue, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; }此时的mRemote.transact()方法已经调用结束,他不仅发起了对服务端的请求,而且带回了服务端的返回值,最后,经过return语句将返回值传递给了客户端。