Android系统进程间通信Binder机制在应用程序框架层(2)

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;   }  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjzdd.html