javaObjectForIBinder查看

本文解析了在Android应用中,serviceManager.getService频繁调用如何通过复用`javaObjectForIBinder`避免频繁创建BinderProxy对象。重点介绍了`javaObjectForIBinder`函数的工作原理,包括自有的对象获取、已存在的对象查找以及新Proxy对象的创建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在应用中多次调用serviveManage.getService(String name)  方法并不会一直造成BinderProxy对象的创建,因为底层会复用proxy对象,

我们可以通过dumpsys meminfo <PID> 来进行查看binder对象的信息。

proxy对象的获取和复用,其实是javaObjectForIBinder里实现的

 

javaObjectForIBinder

vi frameworks/base/core/jni/android_util_Binder.cpp

 

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    if (val == NULL) return NULL;
// val为sp<JavaBBinder>类型时
    if (val->checkSubclass(&gBinderOffsets)) {
        // One of our own!
         //注意,这里是.get方法,是sp的get方法,返回JavaBBinder*指针,再调用object(),得到addService操作时添加的服务对象,并返回该对象
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("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/destruction 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 = jniGetReferent(env, object);
        if (res != NULL) {
            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
            return res;
        }
        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
        android_atomic_dec(&gNumProxyRefs);
        val->detachObject(&gBinderProxyOffsets);
        env->DeleteGlobalRef(object);
    }
//创建BinderProxy对象
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
        // The proxy holds a reference to the native object.
//进行相互关联操作
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        val->incStrong((void*)javaObjectForIBinder);

 
        // 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->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));

 
        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }

 
    return object;
}

 
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    if (obj == NULL) return NULL;
//如果是Binder类及其子类
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;
    }
//如果是BinderProxy类及其子类,在c-AMS-s的过程中会传BinderProxy
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }

 
    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    return NULL;
}

 

kernel-3.18/drivers/staging/android/binder.c

static void binder_transaction(struct binder_proc *proc,
                              struct binder_thread *thread,
                              struct binder_transaction_data *tr, int reply)
{

… …

case BINDER_TYPE_WEAK_HANDLE: {

       struct binder_ref *ref = binder_get_ref(proc, fp->handle);

 

       if (ref == NULL) {

              binder_user_error("%d:%d got transaction with invalid handle, %d\n",

                            proc->pid,

                            thread->pid, fp->handle);

              return_error = BR_FAILED_REPLY;

              goto err_binder_get_ref_failed;

       }

       if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {

              return_error = BR_FAILED_REPLY;

              goto err_binder_get_ref_failed;

       }

//如果client端和target端在同一个进程中

       if (ref->node->proc == target_proc) {

              if (fp->type == BINDER_TYPE_HANDLE)

                     fp->type = BINDER_TYPE_BINDER;

              else

                     fp->type = BINDER_TYPE_WEAK_BINDER;

              fp->binder = ref->node->ptr;

              fp->cookie = ref->node->cookie;

              binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);

              trace_binder_transaction_ref_to_node(t, ref);

              binder_debug(BINDER_DEBUG_TRANSACTION,

                          "        ref %d desc %d -> node %d u%016llx\n",

                          ref->debug_id, ref->desc, ref->node->debug_id,

                          (u64)ref->node->ptr);

       } else {

              … …

       }

} break;

 

case BINDER_TYPE_FD: {

… …

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值