Binder 通信笔记(Java)

本文主要分析Android系统中Java层的Binder通信机制,包括Service的注册、获取service_manager代理、Service初始化、addService过程,以及Binder驱动如何调用Service的业务实现。通过跟随代码,揭示JavaBBinder、BBinder和BinderProxy之间的关系,以及Java层如何与C++层的binder驱动进行交互。

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

概述

在上一节Binder 通信笔记(native)中,分析了在c++层service和client是怎样与binder驱动通信的。在Android中,绝大部分的应用和很多关键的系统Service是用Java来完成的。这一节,我们分析一下Java层程序是如何使用binder驱动进行通信的。其实Java层的binder通信是基于native的,它只是把binder的“网络层”(BpBinder和BBinder)做了一下封装,通过JNI将业务发送给了上一层。先看以下结构图
这里写图片描述

可以看到native层的类关系图和上一节下半部分完全相同,java层多了BinderProxy.class和Binder.class将native层的数据传送到上层。这一节我们只分析上半部分代码,下半部分的代码请查看上一节Binder 通信笔记(native)

Service注册

这一节以ActivityManagerService为例,分析以下Java层Service注册到serviceManager的过程。ActivityManagerService是在SystemServer进程里面注册的,本节以分析binder为主,SystemServer的启动过程这里就不说了,网上有很多资料。大概流程是

SystemServer:main()
    ->run()
        ->startBootstrapServices()
            ->mActivityManagerService.setSystemProcess();
                ->ServiceManager.addService("activity", this, true);

下面看一下ServiceManager.addService的实现。

public static void addService(String name, IBinder service, boolean allowIsolated) {
        try {
            getIServiceManager().addService(name, service, allowIsolated);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

获取service_manager代理

在Java层有一个ServiceManager.class作为service_manager的代理,它是如何实现的呢,我们继续跟代码,看一下getIServiceManager()

private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

ServiceManager是一个单例实现,第一次初始化执行了ServiceManagerNative.asInterface(BinderInternal.getContextObject()) 。先看一下括号里吗的参数。BinderInternal.getContextObject() 是一个native函数。它的实现在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(NULL); 上一篇博客已经分析过,它返回了BpBinder(0), 这个0就代表着远程为service_manager。继续看一下javaObjectForIBinder();

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    if (val == NULL) return NULL;

    //1
    if (val->checkSubclass(&gBinderOffsets)) {
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }

    AutoMutex _l(mProxyLock);

      jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    // 2
    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);
    }

    //3
    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->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值