`
bywyu
  • 浏览: 20191 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

Android平台——Binder机制

阅读更多
由代码来补充部分:

int main(int argc, char** argv)

{

    sp<ProcessState> proc(ProcessState::self());

    sp<IServiceManager> sm = defaultServiceManager();

    LOGI("ServiceManager: %p", sm.get());

    AudioFlinger::instantiate();

    MediaPlayerService::instantiate();

    CameraService::instantiate();

    ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();

}

sp<ProcessState> proc(ProcessState::self()),这一行代码会建立ProcessState对象,一个进程只有唯一的一个ProcessState对象,而ProcessState类的作用是来打开/dev/binder设备。这也就说明了一个问题,一个进程只不可能同时存在多个对/dev/binder的操作。

sp<IServiceManager> sm = defaultServiceManager(),这一行代码要做的事情参见上图。1、创建一个BpBinder。2、由BpBinder对象创建BpServiceManger对象。(为什么要采取如此不自然的方式,可以看一下这两个对象继承的基类)。完成这一步骤的最重要的作用在于以后对于IServiceManager对象的方法的调用,都将会由其子类BpServiceManger的方法来实现(这样做的意义何在?这样的作用仅仅在于我们可以重用IServiceManager的代码,别忘了我们还有一个类似的继承自IServiceManager的类,它叫做BnServiceManger)。这样说起来似乎过于抽象,好在我们可以举一个例子,接下去的代码就会有例子出现。

CameraService::instantiate(),这一行的代码(前面还有两行?相信我,他们绝对是几乎一样的实现,当然我是指从Binder层来说,而不是指与硬件相关的交互)。我们仍然先画出结构图:

我们需要一点代码来辅助我们的分析,CameraService::instantiate的代码如下:

void CameraService::instantiate() {

    defaultServiceManager()->addService(

            String16("media.camera"), new CameraService());

}。

仍然是由defaultServiceManager函数开始,但是我们此时已经拥有了对象,而这样做的目的仅仅在于我们调用的会是BpServiceManger类中的addService方法,而不是IServiceManager基类的addService方法。我们试着去寻找BpServiceManger类中的addService函数。在此之前有个需要我们注意的地方new CameraService,这里实例化了一个CameraService对象,他的基类们是我们要注意的,因为之后我们将不得不关注于整套虚函数调用的机制。CameraService类的继承关系我在图中已经画出:IBinder->BBinder(ICmaerService两个基类)->BnInterface->BnCamerService->CamerService,看起来足够复杂,不幸的是这个继承模式是有意义的。

我们将思路再拉回来,接着看BpServiceManger类中addService的实现:

virtual status_t addService(const String16& name, const sp<IBinder>& service)

{

        Parcel data, reply;

        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

        data.writeString16(name);

        data.writeStrongBinder(service);

        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

        return err == NO_ERROR ? reply.readInt32() : err;

}

Data.writeInterfaceToken与data.writeString这两行我们无需关注,因为它们完成一些接口命名之类的事情。来看看data.writeStrongBinder会做些什么:

status_t Parcel::writeStrongBinder(const sp<IBinder>& val)

{

    return flatten_binder(ProcessState::self(), val, this);

}

而flatten_binder代码如下:

status_t flatten_binder(const sp<ProcessState>& proc,

    const sp<IBinder>& binder, Parcel* out)

{

    flat_binder_object obj;

  

    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

    if (binder != NULL) {

        IBinder *local = binder->localBinder();

        if (!local) {

            BpBinder *proxy = binder->remoteBinder();

            if (proxy == NULL) {

                LOGE("null proxy");

            }

            const int32_t handle = proxy ? proxy->handle() : 0;

            obj.type = BINDER_TYPE_HANDLE;

            obj.handle = handle;

            obj.cookie = NULL;

        } else {

            obj.type = BINDER_TYPE_BINDER;

            obj.binder = local->getWeakRefs();

            obj.cookie = local;

        }

    } else {

        obj.type = BINDER_TYPE_BINDER;

        obj.binder = NULL;

        obj.cookie = NULL;

    }

  

    return finish_flatten_binder(binder, obj, out);

}

我们先来关注IBinder *local = binder->localBinder()这一行代码,binder变量是一个IBinder类的指针,那么是否是说我们要调用的是IBinder类的localBinder函数呢?我去查看代码,发现它是一个虚函数,说明我们将会调用的是指针指向的对象的localBinder函数。还没忘记我们刚才特别提到的地方吧?defaultServiceManager()->addService(String16("media.camera"), new CameraService());它是一个CamerService对象,理论上来说我们应该是按照沿基类向上的方式查找实现,CamerService-> BnCamerService->BnInterface->ICmaerService,BBinder两个基类-> IBinder这样的查找顺序。我们在BBinder类的实现中找到了这个localBinder这个函数,那么这里将会调用的就是BBinder对象的实现:

BBinder* BBinder::localBinder()

{

    return this;

}很明显代码接着会走到橙色部分。

那么finish_flatten_binder又会做些什么呢?代码我就不贴了,它的作用是更新相应的数据偏移量指针。但是写到这里,我们似乎越看越糊涂,这些步骤有什么意义?Parcel类为什么又突然出现了?我们来做一下补充,首先是Parcel类的作用,它是用来完成数据的序列化的,也就是完成数据投递之前的准备工作的。投递的数据都会放在这个类的一个实例中。我去查找Parcel类的定义的时候发现它没有虚函数,也就是说关于投递数据序列化的操作都会在这个类及其实现中完成。我们终于可以暂时的摆脱那些虚函数们了。

我们的工作还远没有结束,我们还没有看到数据是如何投递的?那么我们接着来看addService函数中的最后一个函数调用remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply),它明显是用来投递数据的,如何投递?这里我们要弄清楚两个问题:1、remote函数返回的是什么?也就是transcat是哪个对象的方法。2、transcat如何与底层交互。

我们先来看看第一个问题。先前已经讨论过,addService方法的调用是来自BpServiceManager对象,我们忘了给出另一套类继承的机制:RefBase->IServiceManager,BpRefBase两个基类->BpInterface->BpServiceManager。 那么这里的remote方法(与addService一样均属于BpServiceManager),将会调用BpServiceManager的基类BpRefBase的remote方法。其实现时:inline  IBinder*   remote()   { return mRemote; }。问题在于这里的mRemote会是BBinder呢还是BpBinder?这个讨论使得我们不得不又再次回到之前的代码中去(确实复杂,但还不至于会使人疑惑。)答案在很早以前的defaultServiceManager函数中,之前我们并没有分析过这个函数,是因为我们之前并不需要知道这个函数太多的细节,我们只用知道它是为了完成BpServiceManger对象的建立,但实际上,它还完成了另一个功能,将BpRefBased对象的mRemote成员初始化为BpBinder对象。来看代码:

sp<IServiceManager> defaultServiceManager()

{

    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

  

    {

        AutoMutex _l(gDefaultServiceManagerLock);

        if (gDefaultServiceManager == NULL) {

            gDefaultServiceManager = interface_cast<IServiceManager>(

                ProcessState::self()->getContextObject(NULL));

        }

    }

  

    return gDefaultServiceManager;

}

ProcessState::self()->getContextObject 此函数返回一个BpBinder对象,当然这个对象的指针是其基类指针IBander。然后由interface_cast再次调用,而为mRemote成员的赋值也同样发生在BpServiceManger对象的建立之时,调用BpServiceManger类的构造函数:    BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl),再次调用BpInterface类的构造函数

template<typename INTERFACE>

inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)

    : BpRefBase(remote)

就在绿色的代码部分了,具体的分析请看另一篇文档,这里只是补充。

第一个问题,为我们指明了方向,也就是通讯的时候会采用BpBinder对象的transact函数。这样我们来继续看一下第二个问题,现在我们直奔BpBinder类中的transact函数的实现:

status_t BpBinder::transact(

    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

    // Once a binder has died, it will never come back to life.

    if (mAlive) {

        status_t status = IPCThreadState::self()->transact(

            mHandle, code, data, reply, flags);

        if (status == DEAD_OBJECT) mAlive = 0;

        return status;

    }



    return DEAD_OBJECT;

}
分享到:
评论

相关推荐

    Android系统的Binder机制之一——Service_Manager

    Android系统基于Linux内核,但在进程间通信(IPC)方面并没有采用传统的Linux IPC机制,而是设计并实现了自己的一套轻量级IPC解决方案——Binder机制。该机制不仅提供了高效的进程间通信能力,还为Android框架层提供...

    Android的IPC机制——Binder

    android技术内幕--系统卷,第三章Android的IPC机制,关于Binder通信机制,详细讲解,并附有framework层代码说明,

    Android的IPC机制——Binder 杨丰盛

    Android的IPC机制——写的比较深入的文章,详细介绍了binder的原理 work 版

    android通信机制binder实例

    Binder机制由服务端、客户端、以及一个中间代理——Binder驱动共同构成。 二、Binder组件 1. 服务端:通常是一个运行在其他进程的Service,提供接口供客户端调用。 2. 客户端:调用服务端接口的应用程序,位于与...

    Android系统的Binder机制之二——服务代理对象(1).docx

    在Android系统中,Binder机制是实现跨进程通信的关键组件,它允许不同进程间的服务共享和交互。本篇文章主要探讨的是Binder机制中的服务代理对象(Service Proxy Object),特别是BpBinder的核心概念。 首先,服务...

    从java到C解析Binder机制

    Binder机制是Android系统中核心的进程间通信(IPC)方式,它是一种C/S架构,主要由Client、Server和ServiceManager三部分组成。ServiceManager是Google设计的一段简洁的C代码,它的作用在于集中管理系统的各种服务,...

    Android系统的Binder机制之三——服务代理对象(2).docx

    在Android系统中,Binder机制是实现进程间通信(IPC,Inter-Process Communication)的核心组件。在上一部分我们探讨了C/C++层面的服务代理对象BpBinder以及Binder底层处理方式。现在我们将深入研究Java层面上服务...

    Android进程间通信-Binder机制

    ### Android进程间通信——Binder机制 #### 一、简要介绍和学习计划 在Android操作系统中,每一个应用程序通常由多个组件如Activity和服务(Service)组成。这些组件可能运行在同一进程中,也可能分布在不同进程中。...

    Android Binder设计与实现——设计篇

    Binder机制基于Client-Server通信模型,这种模型已经在多种平台和应用领域得到广泛使用。在Android系统中,许多功能服务都由不同的Server进程负责提供,而Client进程通过IPC与这些Server进行通信。与传统的IPC通信...

    android binder 简单实例

    总结来说,“Android Binder简单实例”涉及到Android系统中进程间通信的核心技术——Binder,以及其基本的C/S架构和通信流程。通过学习和分析提供的代码示例,开发者能够更好地理解和掌握Binder在实际应用中的使用。

    安卓Android源码——安卓Android电子麦克风.zip

    它是Java层的一部分,与HAL通过Binder机制通信。开发者可以通过`AudioRecord`实例创建并配置一个音频记录会话,指定采样率、位深度、声道数量等参数。同时,`MediaRecorder`类也可以用于录音,提供了更高级别的抽象...

    android binder

    根据之前的博文介绍,《Android系统的Binder机制之二——服务代理对象(1)》,`ProcessState`对象负责管理Service的代理对象,确保进程能够正确地使用Binder机制进行通信。 2. **Service注册**: Mediaserver中...

    安卓Android源码——Android Launcher 源码修改可编译.zip

    它通过Binder机制与其他系统服务通信,获取应用信息和用户权限。 3. **编译Android源码**:要编译Android源码,开发者需要搭建AOSP(Android Open Source Project)环境,安装必要的工具如Repo、JDK、NDK等,并执行...

    安卓Android源码——电池监控.zip

    总的来说,"安卓Android源码——电池监控.zip"提供了研究Android电池监控机制的宝贵资源,对于Android开发者尤其是系统级开发者来说,这是一个深入学习和提高的好材料。通过对源码的解析和实践,可以掌握Android系统...

    安卓Android源码——应用程序间的通信介绍.zip

    Android系统的许多核心服务如Content Provider、Broadcast Receiver和Service都是通过Binder机制实现的。Binder机制包括客户端(Client)、服务端(Server)和中介(Binder Driver),其中服务端在一个单独的进程中...

Global site tag (gtag.js) - Google Analytics