Android Binder总结

1. MediapplayerService 的启动,怎样在ServiceManager注冊的,不解说详细的细节

ServiceManager 是整个系统的Service总管,其余的系统服务都是通过defaultServiceManager的远程接口来调用ServiceManager。Service获得ServiceManager的接口之后就会把自己加入到ServiceManager中,然后把自己启动起来,之后等待着Client端的请求连接。

关于SystemManager怎样启动而且成为总管和Binder的知识能够參考:

http://blog.csdn.net/luoshengyang/article/details/6621566

先看一下MediaPlayerService的UML,有个总体的了解。

1) 首先MediaPlayerService 是从main_mediaservice.cpp main中进行实例化,所以MediaPlayerService也执行在system_service的进程中。

int main(int argc, char** argv)
{
    ProcessState> proc(ProcessState::self());
    ... ...
    MediaPlayerService::instantiate();
    ... ...
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

2) 在MediaPlayerService::instantiate()中主要做了两件事情,第一就是通过 ProcessState::self() 来初始化一个全局变量gProcess,在ProcessState中的mDriverFD会保存Binder设备的指针。第二个 主要工作就是调用ServiceManager把自己new一个出来然后加入到ServiceManger总管中。

sp<ProcessState> ProcessState::self()
{
    if (gProcess != NULL) return gProcess;

    AutoMutex _l(gProcessMutex);
    if (gProcess == NULL) gProcess = new ProcessState;
    return gProcess;
}

addService的过程非常复杂,有兴趣的人能够拜读一下老罗的这篇文章:

http://blog.csdn.net/luoshengyang/article/details/6629298

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

3)  在把自己增加到ServiceManager中之后,会运行下面两个函数,总要是用来通过调用talkWithDriver函数来和Binder驱动程序进行交互,实际上就是调用talkWithDriver来等待Client的请求,然后再调用executeCommand来处理请求,而在executeCommand函数中,终于会调用BBinder::transact来真正处理Client的请求

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

2. 怎样去调用MediaPlayerService 而且和service通信

MediaPlayerService此时已经是一个Service了,如今就等着Client端去建立连接。这个Client就是MediaPlayer,它声明和实如今frameworks/base/include/media/mediaplayer.h和frameworks/base/media/libmedia/mediaplayer.cpp文件里。MediaPlayer继承于IMediaDeathNotifier类,这个类声明和实如今frameworks/base/include/media/IMediaDeathNotifier.h和frameworks/base/media/libmedia//IMediaDeathNotifier.cpp文件里,里面有一个静态成员函数getMeidaPlayerService,它通过IServiceManager::getService接口来获得MediaPlayerService的远程接口。

在介绍IMediaDeathNotifier::getMeidaPlayerService函数之前,我们先了解一下这个函数的目标,实际上就是要获得一个称为BpMediaPlayerService对象的IMediaPlayerService接口。

从之前那个类图能够看到,BpMediaPlayerService继承于BpInterface<IMediaPlayerService>类,即BpMediaPlayerService继承了IMediaPlayerService类和BpRefBase类,这两个类又分别继续了RefBase类。BpRefBase类有一个成员变量mRemote,它的类型为IBinder,实际是一个BpBinder对象。BpBinder类使用了IPCThreadState类来与Binder驱动程序进行交互,而IPCThreadState类有一个成员变量mProcess,它的类型为ProcessState,IPCThreadState类借助ProcessState类来打开Binder设备文件/dev/binder,因此,它能够和Binder驱动程序进行交互。

BpMediaPlayerService的构造函数有一个參数impl,它的类型为const sp<IBinder>&,从上面的描写叙述中,这个实际上就是一个BpBinder对象。这样,要创建一个BpMediaPlayerService对象,首先就要有一个BpBinder对象。再来看BpBinder类的构造函数,它有一个參数handle,类型为int32_t,这个參数的意义就是请求MediaPlayerService这个远程接口的进程对MediaPlayerService这个Binder实体的引用了。因此,获取MediaPlayerService这个远程接口的本质问题就变为从Service
Manager中获得MediaPlayerService的一个句柄了。

我们就以create的过程作为一个样例:

1) MediaPlayer.getMediaPlayerService()

MediaPlayer继承IMediaDeathNotifier,所以就是调用IMediaDeathNotifier.getMediaPlayerService(),这个函数的主要作用就是从SystemManager中获取"media.player" Service的IBinder,也就是获取一个BpMediaPlayerService,通过这个IBinder与服务端通信。

2) service->create(getpid(), this, mAudioSessionId)

这个service实际上就是BpMediaPlayerService,所以就是调用BpMediaPlayerService的create,在这个函数中回去调用remote()->transact。

3) remote()->transact(CREATE, data, &reply)

这个remote()返回的是一个BpBinder, 实际上就是BpBinder.transact,这个transact自己是不做什么事情的,主要是通过调用IPCThreadState->transact去完毕数据请求工作。

4) IPCThreadState::self()->transact

在这个transact中主要通过waitForResponse和talkWithDriver去完毕与Binder设备的ioctl操作。当调用talkWithDriver之后,MediaPlayerService中的IPCThreadState就用监听到请求而且调用自己的executeCommand。

5) BnMediaPlayerService.onTransact()

在executeCommand会依据command的类型去调用回调函数,这里就是调用BBinder.transact, 而BBinder.transact终于会调用BnMediaPlayer.onTransact去做详细的处理,调用create然后返回一个Mediaplayer的一个Ibinder的client。

3.  以AMS为样例,看一下Java层的Service Binder是假设去使用。AMS怎样去拿到Client,Client怎样和Service通信

1) Instrumentation.execStartActivity()

Activity里面有一个StartActivity函数回去调用Instrumentation.execStartActivity(), 而在execStartActivity()又会通过ActivityManagerNative.getDefault()去掉用startActivity

2) ActivityManagerProxy.transact()

在ActivityManagerNative.getDefault()事实上返回的就是ActivityManagerProxy。在ActivityManagerProxy的startActivity会调用mRemote.transact,而mRemote事实上BinderProxy对象,所以等于直接调用BinderProxy的trasact函数。

3)Binder.exectransact()

BinderProxy的trasact会去通过JNI的来完毕Binder的请求,最后由服务端的Binder的execTranaction去做函数响应。

4) ActivityManagerService.onTransact

Biner.execTranaction使用ActivityManagerService.onTransact最为回调函数去运行,并将结果放在reply中。

UML图:

http://sdrv.ms/Q79iGk

时间: 2024-10-22 09:52:00

Android Binder总结的相关文章

[gitbook] Android框架分析系列之Android Binder详解

请支持作者原创: https://mr-cao.gitbooks.io/android/content/android-binder.html Android Binder详解 Table of Contents 1. binder简介 2. binder的实现 2.1. IBinder类简介 2.2. IInterface类简介 2.3. BpBinder和BBinder简介 2.4. ProcessState和IPCThreadState简介 2.5. ServiceManager简介 2.

转:轻松理解 Android Binder,只需要读这一篇

转自http://www.jianshu.com/p/bdef9e3178c9 在 Android 系统中,Binder 起着非常重要的作用,它是整个系统 IPC 的基石.网上已经有很多文章讲述 Binder 的原理,有的讲的比较浅显,没有触及到关键,有的讲的太过于深入底层,难以理解,本文会比较全面,以一个比较轻松的方式,从面到点,大处着眼,小处着手的形式去讲述 Binder 在 Android 中是如何使用的.理解 Binder 的基本原理,对学习 Android 也有很大的帮助,很多问题也能

android binder 机制二(client和普通server)

在讲它们之间的通信之前,我们先以MediaServer为例看看普通Server进程都在干些什么. int main() { -- // 获得ProcessState实例 sp<ProcessState> proc(ProcessState::self()); // 得到ServiceManager的Binder客户端实例 sp<IServiceManager> sm = defaultServiceManager(); -- // 通过ServiceManager的Binder客户

Android Binder进程间通信---ServiceManager代理对象的获取过程

本文参考<Android系统源代码情景分析>,作者罗升阳. 一.测试代码: -/Android/external/binder/server ----FregServer.cpp ~/Android/external/binder/common ----IFregService.cpp ----IFregService.h ~/Android/external/binder/client ----FregClient.cpp Binder库(libbinder)代码: ~/Android/fr

Android Binder分析二:Natvie Service的注冊

这一章我们通过MediaPlayerService的注冊来说明怎样在Native层通过binder向ServiceManager注冊一个service,以及client怎样通过binder向ServiceManager获得一个service,并调用这个Service的方法. Native Service的注冊 这里以MediaPlayerService举例来说明怎样在Native层注冊Service,首先来看main_mediaservice.cpp的main方法: int main(int a

Android Binder设计与实现篇

摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势.深入了解Binder并将之与传统IPC做对比有助于我们深入领会进程间通信的实现和性能优化.本文将对Binder的设计细节做一个全面的阐述,首先通过介绍Binder通信模型和Binder通信协议了解Binder的设计需求:然后分别阐述Binder在系统不同部分的表述方式和起的作用:

Android Binder进程间通信---注册Service组件---发送和处理BC_REPLY返回协议

本文参考<Android系统源代码情景分析>,作者罗升阳 一.测试代码: -/Android/external/binder/server ----FregServer.cpp ~/Android/external/binder/common ----IFregService.cpp ----IFregService.h ~/Android/external/binder/client ----FregClient.cpp Binder库(libbinder)代码: ~/Android/fra

Android Binder机制浅析

Binder是Android上一种IPC机制,重要且较难理解.由于Linux上标准IPC在灵活和可靠性存在一定不足,Google基于OpenBinder的设计和构想实现了Binder. 本文只简单介绍其实现,并重点讨论Binder安全相关的内容.详细的Binder设计与实现分析,参考附录4篇文章. 一.Binder 实现 Android Binder由Client.Server.Service Manager和Binder驱动4个部件组成,下图引自网络. 在类UNIX系统中,进程是相互独立的,一

Android Binder机制分析(5) Binder_ioctl()分析

引言 在博客Android Binder机制(3)本地服务注册过程这篇博客中我们详细讲解了本地服务的注册过程,除了一个地方之外,那就是IPCThreadState::waitForResponse()方法中的talkWithDriver(),而在talkWithDriver()中调用了binder_ioctl(),由于内容太多,所以专门写一篇博客进行分析. 实际上,不只是在服务注册过程中会调用到Binder Driver中的binder_ioctl(),在服务检索.服务使用阶段都会调用到bind

Android Binder进程间通信---Binder类图

上传两张Binder类图,有助于理解Binder进程间通信: Android Binder进程间通信---Binder类图