ServiceManager.java里面有个getIServiceManager。
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
BinderInternal.getContextObject()实际调用到了android_os_BinderInternal_getContextObject,android_utils_binder.cpp这个文件里面。
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
这里的b是一个BpBinder,c++层的。
这个javaObjectForIBinder这个很重要。从名字上看是从ibinder创建一个javaobject。
重要的代码如下:
gBinderProxyOffsets.mClass是int_register_android_os_BinderProxy里面定义的,对应的java层的类是android/os/BinderProxy,
BinderProxy这个类定义在Binder.java文件里面
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
这个object 对象是一个BinderProxy的对象。
if (object != NULL) {
LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object.
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
给BinderProxy的成员变量object赋值val.get(),是个int值,这个地方val.get()没查到这个函数。val是刚才创建的BpBinder对象。
翻译是,代理端有个本地对象的引用。
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);
// Also remember the death recipients registered on this proxy
sp<DeathRecipientList> drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;这里返回的对象就是BinderProxy
android_os_BinderInternal_getContextObject返回的就是BinderProxy端的一个对象。
ServiceManagerNative.asInterface又对这个BinderProxy进行了转换,创建了ServiceManagerProxy这个对象,这个过程和底层c++层类似。
getIServiceManager返回的就是ServiceManagerProxy对象。
那这个ServiceManagerProxy是如何和底层通信的。
以getService获取服务为例。
从ServiceManager.java里面的getService开始。
return getIServiceManager().getService(name);,这里getService调用的就是ServiceManagerProxy这个里面的。
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);使用了mRemote对象,这个对象就是BinderProxy对象。这个transact对应的就是BinderProxy里面的transact,对应到jni层android_os_BinderProxy_transact,
parcelForJavaObject,这个函数从字义上看就是将java层面的parcel对象转换成本地的parcel对象。
里面有个gParcelOffsets变量,初始化在int_register_android_os_Parcel里面
类对应的就是android/os/Parcel,获取这个对象的mObject对应的parcel,这个地方mObject应该赋值过。
android_os_Parcel_init地方,创建了一个本地parcel对象,并把这个对象给第二个参数的mObject对象进行了赋值。
这个init是在Parcel构造函数里面调用的。找到头了。
parcelForJavaObject这个函数获得的对象实际上就是parcel.cpp的一个对象了。
下面又涉及到gBinderProxyOffsets,这个地方是不是和parcel类似呢?我们找找给对象的gBinderProxyOffsets.mObject这个变量赋值的地方
int_register_android_os_BinderProxy这里面调用了gBinderProxyOffsets.mClass这个对应的类是android/os/BinderProxy
这里构造了一个BinderProxy的对象。javaObjectForIBinder我们一开始分析了这个函数。这个里面创建了一个BinderProxy对象,
javaObjectForIBinder这个函数第二个参数传人的是c++层BpBinder对象。
在javaObjectForIBinder里面,将BpBinder对象赋值给了BinderProxy对象的mObject对象。
IBinder* target = (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
这里获得的这个Binder就是BpBinder对象了。
所以这个transact也就是BpBinder的transact了。
但是怎么和ServiceManager联系上呢?这个不用操心了。在底层通过读取parcel里面的描述符得到。不对,底层可以知道,但是这个地方BpBinder如何BpServiceManager联系起来呢?我们漏掉了什么吗?
查看底层,有个BpBinder.cpp文件实现了BpBinder。
忘了在哪里看到过,BpBinder对应的就是BpSercieManager,这个需要确认一下。
IPCThreadState executeCommand里面
sp<BBinder> b((BBinder*)tr.cookie);
这里的b代表的就是一个BB端的对象,这个对象就是根据handle确认的,这里就是BnServiceManager。见书《深入理解android I》p160