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

Android Binder总结的更多相关文章

  1. [转]Android Binder设计与实现 - 设计篇

    摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder ...

  2. (转)Android Binder设计与实现 – 设计篇

    原文地址(貌似已打不开):Android Binder设计与实现 – 设计篇 ------------------------------------------------------------- ...

  3. 图解Android - Binder 和 Service

    在 Zygote启动过程 一文中我们说道,Zygote一生中最重要的一件事就是生下了 System Server 这个大儿子,System Server 担负着提供系统 Service的重任,在深入了 ...

  4. Android Binder设计与实现 - 设计篇

    要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具 ...

  5. Android Binder机制详解:手写IPC通信

    想要掌握一样东西,最好的方式就是阅读理解它的源码.想要掌握Android Binder,最好的方式就是写一个AIDL文件,然后查看其生成的代码.本文的思路也是来自于此. 简介 Binder是Andro ...

  6. Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  7. Android Binder IPC详解-Android学习之旅(96)

    linux内存空间与BInder Driver Android进程和linux进程一样,他们只运行在进程固有的虚拟空间中.一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间 ,用户空间是 ...

  8. ANDROID BINDER机制浅析

    Binder是Android上一种IPC机制,重要且较难理解.由于Linux上标准IPC在灵活和可靠性存在一定不足,Google基于OpenBinder的设计和构想实现了Binder. 本文只简单介绍 ...

  9. (原创)Android Binder设计与实现 - 实现篇(1)

    本文属于原创作品,转载请注明出处并放于明显位置,原文地址:http://www.cnblogs.com/albert1017/p/3849585.html 前言 在学习Android的Binder机制 ...

  10. 图文详解 Android Binder跨进程通信机制 原理

    图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...

随机推荐

  1. jquery li a 样式

    jQuery(".CwebtopNavContainer").find("li:last a").css("color","red ...

  2. ASP.NET Zero--1.如何开始

    1.加群 群号:104390185,下载这个文件并解压 用VS2015打开aspnet-zero-1.9.0.1 2.修改配置文件 Web项目web.config连接字符串 <add name= ...

  3. 易普优APS应用案例:线束行业生产计划排产

    一.线束行业生产现状 (1)产品种类以及标准繁多,生产计划难协调 线束行业的生产,虽然原材料不多,但线束产品却多达几万种.一般线束企业,虽然不是每个月都生产数万种产品,但每月生产的产品品种在300种以 ...

  4. CentOS7.6打开的程序窗口居中

    每次在CentOS7中打开新的窗口都会靠左上角显示,所以每次打开一个窗口都要多做一步操作,将窗口移到屏幕中间来,强迫症的我觉得太麻烦了,所以… 安装ccsm yum -y install  compi ...

  5. 用 Python实现一个ftp+CRT(不用ftplib)

    转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5590004.html  本来最初的想法是实现一个ftp服务器,用来实现用户的登陆注册和文件的断点上传下载等,结果做着 ...

  6. Java反射机制Reflection

    Java反射机制 1 .class文件 2 Class类 3 Class类与反射机制 4 Java反射机制的类库支持及简介 5 反射机制的定义与应用 6 反射机制Demo Java反射机制demo(一 ...

  7. Xamarin.Forms教程开发的Xcode的下载安装

    Xamarin.Forms教程开发的Xcode的下载安装 Xamarin.Forms教程开发的Xcode的下载安装,Xcode是开发iOS应用程序的图形化开发工具.本节将讲解Xamarin.Forms ...

  8. POWEROJ 2610 判断回文串 【HASH】

    题目链接[https://www.oj.swust.edu.cn/problem/show/2610] 题意:给你一个字符串,让你判断这个字符串是不是回文串,字符串的长度是1<len<1e ...

  9. CF336B[思维题]

    题目链接[http://codeforces.com/problemset/problem/336/B] 题意:画出2*m个圆圈,编号为1-m的圆圈在同一行相邻,编号在m+1-2*m的圆圈在同一行,有 ...

  10. 【最大独立集】BZOJ3175- [Tjoi2013]攻击装置

    [题目大意] 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2),(x+2, ...