ServiceManager类有一个静态成员函数getIServiceManager,它的作用就是用来获取Service Manager的Java远程接口了,而这个函数又是通过ServiceManagerNative来获取Service Manager的Java远程接口的。
接下来,我们就看一下ServiceManager.getIServiceManager这个函数的实现,这个函数定义在frameworks/base/core/java/Android/os/ServiceManager.java文件中:
public final class ServiceManager { ...... private static IServiceManager sServiceManager; ...... private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; } ...... }如果其静态成员变量sServiceManager尚未创建,那么就调用ServiceManagerNative.asInterface函数来创建。在调用ServiceManagerNative.asInterface函数之前,首先要通过BinderInternal.getContextObject函数来获得一个BinderProxy对象。
我们来看一下BinderInternal.getContextObject的实现,这个函数定义在frameworks/base/core/java/com/android/internal/os/BinderInternal.java文件中:
public class BinderInternal { ...... /** * Return the global "context object" of the system. This is usually * an implementation of IServiceManager, which you can use to find * other services. */ public static final native IBinder getContextObject(); ...... }
这里可以看出,BinderInternal.getContextObject是一个JNI方法,它实现在frameworks/base/core/jni/android_util_Binder.cpp文件中:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); }
这里看到我们熟悉的ProcessState::self()->getContextObject函数,具体可以参考浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路一文。ProcessState::self()->getContextObject函数返回一个BpBinder对象,它的句柄值是0,即下面语句:
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);相当于是:
sp<IBinder> b = new BpBinder(0);
接着调用javaObjectForIBinder把这个BpBinder对象转换成一个BinderProxy对象:
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; if (val->checkSubclass(&gBinderOffsets)) { // One of our own! jobject object = static_cast<JavaBBinder*>(val.get())->object(); //printf("objectForBinder %p: it's our own %p!\n", val.get(), object); return object; } // For the rest of the function we will hold this lock, to serialize // looking/creation of Java proxies for native Binder proxies. AutoMutex _l(mProxyLock); // Someone else's... do we know about it? jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet); if (res != NULL) { LOGV("objectForBinder %p: found existing %p!\n", val.get(), res); return res; } LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get()); android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { LOGV("objectForBinder %p: created new %p!\n", val.get(), object); // The proxy holds a reference to the native object. env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); val->incStrong(object); // The native object needs to hold a weak reference back to the // proxy, so we can retrieve the same proxy if it is still active. jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object; }