java和c++直接如何进行ipc通信的?


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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值