Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构

转载请把头部出处链接和尾部二维码一起转载,本文出自: http://blog.csdn.net/hejjunlin/article/details/52435789

前面几节中,都是通过java层调用到jni中,jni向下到c++层并未介绍 看下Java层一个方法在c++层 MediaPlayer后续过程 frameworks/av/media/libmedia/MediaPlayer.cpp 找一个我们之前熟悉的setDataResource方法看下C/S模式的过程,亦可参考Android Multimedia框架总结(四)MediaPlayer中从Java层到C++层类关系及prepare及之后其他过程中的图,了解整体上C/S架构。先看下Agenda:

  • 举例setDataSource方法在mediaplayer.cpp之后发生了什么?
  • Client到底是什么?
  • Client及MediaPlayer是什么一种关系?
  • IMediaPlayer.h,mediaplayer.h,IMediaPlayerClient分别做什么?

举例setDataSource方法在mediaplayer.cpp之后发生了什么?

先看下setDataSource方法:

对应看下MediaPlayerService.cpp中createt函数,这里说下MediaPlayerService.cpp位置,6.0源码中是在frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp中。如下:

在new Client中,有一个IPCThreadState,这里介绍下: 在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binder驱动,建立线程池,让其进程里面的所有线程都能通过Binder通信。 与之相关的是IPCThreadState,每个线程都有一个IPCThreadState实例登记在Linux线程的上下文附属数据中,主要负责 Binder的读取,写入和请求处理框架。IPCThreadState在构造的时候获取进程的ProcessState并记录在自己的成员变量mProcess中,通过mProcess可以获得Binder的句柄。详细了解ProcessStata及IPCThreadState源码,可以参考:《Binder中的ProcessState和IPCThreadState分析》,写的很不错,IPCThreadState通过IPCThreadState::transact把data,及handle等填充入binder_transaction_data,在两个进程间通信。

Client到底是什么?

这里这个Client到底是什么?我们又得追踪下,在frameworks/av/media/libmediaplayerservice/MediaPlayerService.h如下:

以上代码没有省略,是因为确实对我们理解从Java层过来的MediaPlayer相关方法,在这都有对应。如果还记得前面《Android Multimedia框架总结(四)MediaPlayer中从Java层到C++层类关系及prepare及之后其他过程》文章中那个图的话,可以从整体上理解这个Client属于什么角色及位置。继承BnMediaPlayer,并包含了IMediaPlayer相关接口。 总结下上面代码:Client类的继承关系为:Client->BnMediaPlayer->IMediaPlayer分析上面代码,可以看出create方法,是构造了一个Client对象,并且将此client对象添加到mediapalyerservice类的全局列表中:mClients,是一个SortedVector,紧接着执行player->setDataSource(url, headers),即Clients::setDataSource,因此在setDataSource中的

语句相当于

即player最终是用Client对象来初始化,可以直接认为player==client 本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52435789

Client及MediaPlayer是什么关系?

这是候问题来了?在C++中,这个Client及MediaPlayer又是什么一种关系呢?

  • Client是MediaPlayerService内部的一个类,我们从上面代码已知,因为MediaPlayerService运行在服务端,故Client也是运行在服务端。
  • Client在MediaPlayerService.h中,那接着看下MediaPlayerService中的实现,实现过程中调用过了MediaPlayerService类的一些函数,同样回到setDataSource

接下来看MediaPlayer中,以下代码中在frameworks/av/include/media/mediaplayer.h中:

这里函数和Client中的函数时一一对应的,两者通过Client的代理类联系在了一起。

上面两个函数,一个是MediaPlayer的setDataSouree,然后里面会调到attachNewPlayer函数,这个函数最终会调用到服务端Client的对应的函数, 本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52435789

IMediaPlayer.h,mediaplayer.h,IMediaPlayerClient分别做什么?

到这里,可能有人会想:IMediaPlayer.h,及mediaplayer.h的区别是什么?总结主要如下(另加一个IMediaPlayerClient.h,一起介绍):

  • 从包结构:首先IMediaPlayer和IMediaPlayerClient.h都是在frameworks/av/media/libmedia包下,而mediaplayer.h是在/av/include/media包下。(前面已有代码贴出)
  • 从功能上看:它们担当职责也不一样

这里贴出IMediaPlayer.h及IMediaPlayerClient.h代码: IMediaPlayer.h位于frameworks/av/media/libmedia下:

IMediaPlayer.h中定义的基本上都是虚函数,而我们知道虚函数在C++中就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。所以它的功能是一个实现MediaPlayer功能的接口,看到那个onTransact方法,自然联想Binder通信,把底层的Parcel指针类型数据向上层向另一个进程中传递。 再看下IMediaPlayerClient.h,同样位于frameworks/av/media/libmedia下:

  • 上面代码总结为:在内部定义一个BpMediaPlayerClient(也就是Client的父类),然后它也有一个onTransact,一般onXXX都是属于背动回调过来的,不是由自己控制,如Activity中onCreate,onPause,onStart,这些都是在其他地方处理,通知到Actvitity中的。这里也是一样,onTransact作为Binder通信中的回调方法,前面《Android Multimedia框架总结(四)MediaPlayer中从Java层到C++层类关系及prepare及之后其他过程》中介绍到player实际上是C/S模式整体,IMediaPlayerClient.h的功能是描述一个MediaPlayer客户端的接口。
  • 最后总结下:mediaplayer.h的功能是对外(jni层)的接口类,它最主要是定义了一个MediaPlayer类(C++层),我们在android_media_MediaPlayer.cpp中就引入了media/mediaplayer.h,IMediaPlayer.h则是一个实现MediaPlayer(C++层)功能的接口,而IMediaPlayerClient.h的功能是描述一个MediaPlayer客户端(这里暂理解为前面说的Client)的接口。

原文发布于微信公众号 - 何俊林(DriodDeveloper)

原文发表时间:2016-09-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏阿杜的世界

Java Web技术经验总结(十七)

862
来自专栏开发之途

Android 模拟登陆网站实现移动客户端

5798
来自专栏Java Web

初学Java Web(7)——文件的上传和下载

文件上传 文件上传前的准备 在表单中必须有一个上传的控件 <input type="file" name="testImg"/> 因为 GET 方式有请求大...

4205
来自专栏向治洪

Android启动过程分析

Android系统启动过程 首先看一张Android框架结构图 ? Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应...

2176
来自专栏Java帮帮-微信公众号-技术文章全总结

Java文件上传下载实训

文件上传概述 1 文件上传的作用 例如网络硬盘!就是用来上传下载文件的。 在智联招聘上填写一个完整的简历还需要上传照片呢。 2 文件上传对页面的要求 上传文件的...

5495
来自专栏zhisheng

渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)

上篇文章写完了 ES 流程启动的一部分,main 方法都入口,以及创建 Elasticsearch 运行的必须环境以及相关配置,接着就是创建该环境的节点了。

1573
来自专栏向治洪

Hibernate入门

Hibernate是什么     Hibernate是一个轻量级的ORMapping框架     ORMapping原理(Object Relational M...

2116
来自专栏高性能服务器开发

redis网络通信模块源码分析(上)

时下的业界,相对于传统的关系型数据库,以key-value思想实现的nosql内存数据库也是非常流行,而提到内存数据库,很多人第一反应就是redis。确实,re...

4163
来自专栏Jerry的SAP技术分享

Hybris Enterprise Commerce Platform 服务层的设计与实现

Hybris Enterprise Commerce Platform这个系列之前已经由我的同事,SAP成都研究院Hybris开发团队的同事张健(Zhang J...

1132
来自专栏cmazxiaoma的架构师之路

IDEA入门(1)--lombok和Junit generator2插件的运用

2393

扫码关注云+社区

领取腾讯云代金券