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

它实际上只做了一件事情,就是创建一个JavaBBinderHolder对象jbh,然后把这个对象的地址保存在上面的Binder类的mObject成员变量中,后面我们会用到。

回到ServerThread.run函数中,我们再来看一下ServiceManager.addService函数的实现:

public final class ServiceManager {       ......          private static IServiceManager sServiceManager;          ......          public static void addService(String name, IBinder service) {           try {               getIServiceManager().addService(name, service);           } catch (RemoteException e) {               Log.e(TAG, "error in addService", e);           }       }          ......      }  

这里的getIServiceManager函数我们在前面已经分析过了,它返回的是一个ServiceManagerProxy对象的IServiceManager接口。因此,我们进入到ServiceManagerProxy.addService中去看看:

class ServiceManagerProxy implements IServiceManager {       public ServiceManagerProxy(IBinder remote) {           mRemote = remote;       }          ......          public void addService(String name, IBinder service)           throws RemoteException {               Parcel data = Parcel.obtain();               Parcel reply = Parcel.obtain();               data.writeInterfaceToken(IServiceManager.descriptor);               data.writeString(name);               data.writeStrongBinder(service);               mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);               reply.recycle();               data.recycle();       }          ......          private IBinder mRemote;   }  

这里的Parcel类是用Java来实现的,它跟我们前面几篇文章介绍Binder机制时提到的用C++实现的Parcel类的作用是一样的,即用来在两个进程之间传递数据。

这里我们关注是如何把参数service写到data这个Parcel对象中去的:

data.writeStrongBinder(service);  

我们来看看Parcel.writeStrongBinder函数的实现:

public final class Parcel {       ......          /**      * Write an object into the parcel at the current dataPosition(),      * growing dataCapacity() if needed.      */       public final native void writeStrongBinder(IBinder val);          ......   }  

这里的writeStrongBinder函数又是一个JNI方法,它定义在frameworks/base/core/jni/Android_util_Binder.cpp文件中:

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)   {       Parcel* parcel = parcelForJavaObject(env, clazz);       if (parcel != NULL) {           const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));           if (err != NO_ERROR) {               jniThrowException(env, "java/lang/OutOfMemoryError", NULL);           }       }   }  

       这里的clazz参数是一个Java语言实现的Parcel对象,通过parcelForJavaObject把它转换成C++语言实现的Parcel对象。这个函数的实现我们就不看了,有兴趣的读者可以研究一下,这个函数也是实现在frameworks/base/core/jni/android_util_Binder.cpp这个文件中���
       这里的object参数是一个Java语言实现的Binder对象,在调用C++语言实现的Parcel::writeStrongBinder把这个对象写入到parcel对象时,首先通过ibinderForJavaObject函数把这个Java语言实现的Binder对象转换为C++语言实现的JavaBBinderHolder对象:

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)   {       if (obj == NULL) return NULL;          if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {           JavaBBinderHolder* jbh = (JavaBBinderHolder*)               env->GetIntField(obj, gBinderOffsets.mObject);           return jbh != NULL ? jbh->get(env) : NULL;       }          if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {           return (IBinder*)               env->GetIntField(obj, gBinderProxyOffsets.mObject);       }          LOGW("ibinderForJavaObject: %p is not a Binder object", obj);       return NULL;   }  

我们知道,这里的obj参数是一个Binder类的实例,因此,这里会进入到第一个if语句中去。

在前面创建HelloService对象,曾经在调用到HelloService的父类Binder中,曾经在JNI层创建了一个JavaBBinderHolder对象,然后把这个对象的地址保存在Binder类的mObject成员变量中,因此,这里把obj对象的mObject成员变量强制转为JavaBBinderHolder对象。

到了这里,这个函数的功课还未完成,还剩下最后关键的一步:

return jbh != NULL ? jbh->get(env) : NULL;  

这里就是jbh->get这个语句了。

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

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