BpMediaExtractorService BnMediaExtractorService IMediaExtractorService MediaExtractorService 关系
Android媒体框架中,MediaExtractorService的实现遵循Binder跨进程通信标准设计:IMediaExtractorService作为根接口定义方法规范,由AIDL自动生成BnMediaExtractorService(服务端骨架)和BpMediaExtractorService(客户端代理),而MediaExtractorService则是开发者手动实现的业务逻辑类。从A
重点:核心关注MediaExtractorService 是需要自己实现的 其它的都是aidl 自动生成的。
在 Android 媒体框架的 Binder 跨进程通信体系中,BpMediaExtractorService、BnMediaExtractorService、IMediaExtractorService、MediaExtractorService 是围绕media.extractor服务形成的接口定义 - 跨进程代理 - 跨进程服务端 - 实际业务实现四层核心关系,且该关系遵循 Android Binder 开发的标准设计规范(AIDL 自动生成 + 手动实现业务逻辑)。结合你关注的 Android 9/10 + 版本、media.extractor服务场景,以下从核心定义、层级关系、代码生成 / 实现、调用链路四个维度讲透,同时明确版本差异细节:
一、先明确核心前提(Binder 开发通用规则)
这四个类的关系建立在Android AIDL 跨进程通信基础上,核心规则:
- 开发者编写AIDL 接口文件,编译工具会自动生成 3 个核心类:
- 基接口类(如
IMediaExtractorService):定义跨进程通信的方法规范; - BnXXX(如
BnMediaExtractorService):Binder服务端基类(Binder Native),运行在服务提供进程(media.extractor进程),需子类实现抽象方法; - BpXXX(如
BpMediaExtractorService):Binder客户端代理类(Binder Proxy),运行在服务调用进程(如 MediaServer、应用进程),负责将方法调用转发给服务端;
- 基接口类(如
- 开发者需手动实现一个业务类(如
MediaExtractorService),继承 BnXXX 并实现抽象方法,作为跨进程服务的实际业务逻辑载体。
二、四个类的核心定义与层级关系(从顶层到实现)
四层关系呈 **「接口定义→服务端基类→实际业务实现」「接口定义→客户端代理」** 分支结构,核心是IMediaExtractorService 为所有类的根接口,Bn/Bp 为 AIDL 自动生成的跨进程通信骨架,MediaExtractorService 为手动实现的实际业务类。
1. 根接口:IMediaExtractorService(AIDL 生成,方法规范)
- 生成来源:由 AIDL 文件
frameworks/av/media/libmedia/IMediaExtractorService.aidl编译自动生成,对应头文件IMediaExtractorService.h; - 核心作用:定义
media.extractor服务的跨进程通信方法规范,所有 Bn/Bp/MediaExtractorService 都需遵循该规范,核心方法如:cpp
运行
// 核心跨进程方法:创建MediaExtractor实例(NuPlayer/GenericSource核心调用) virtual sp<IMediaExtractor> createExtractor( const String16& path, const ParcelFileDescriptor& fd, const String16& mime) = 0; // 获取服务支持的媒体格式列表 virtual Vector<String16> getSupportedTypes() = 0; - 关键特性:纯虚接口类,无任何实现代码,仅作为所有相关类的方法约定。
2. Binder 服务端基类:BnMediaExtractorService(AIDL 生成,通信骨架)
- 生成来源:同上述 AIDL 文件编译自动生成,继承自
IMediaExtractorService和 Android Binder 核心类BBinder; - 核心作用:作为
media.extractor服务端的Binder 通信骨架,运行在 **media.extractor独立进程 **(Android 10+)/MediaServer 进程(Android 9),核心能力:- 实现 Binder 跨进程通信的底层逻辑(数据序列化 / 反序列化、进程间方法转发);
- 暴露纯虚抽象方法(与
IMediaExtractorService的方法一一对应),要求子类必须实现; - 作为服务端的 “入口”,接收客户端(Bp)的跨进程调用请求。
- 关键特性:仅提供通信骨架,无任何媒体业务逻辑,无法直接实例化(含纯虚方法)。
3. 实际业务实现:MediaExtractorService(手动实现,业务核心)
- 实现来源:由 Android 系统开发人员手动编写,源码位置
frameworks/av/media/extractors/MediaExtractorService.cpp; - 核心作用:作为
media.extractor服务的实际业务逻辑载体,是createExtractor等方法的真实实现者,核心能力:- 继承
BnMediaExtractorService,实现其所有纯虚抽象方法; - 完成媒体解封装的核心业务:创建
MediaExtractor实例、适配 TS/MP4/FLV 等格式、校验权限、返回IMediaExtractor接口给客户端; - 是
media.extractor服务的核心价值体现,所有跨进程调用最终都会落到此类的方法实现上。
- 继承
- 关键特性:可实例化,是
media.extractor服务注册到 ServiceManager 的实际对象。
4. Binder 客户端代理:BpMediaExtractorService(AIDL 生成,请求转发)
- 生成来源:同上述 AIDL 文件编译自动生成,继承自
IMediaExtractorService和 Android Binder 核心类BpRefBase; - 核心作用:作为
media.extractor客户端的跨进程代理,运行在服务调用进程(如 NuPlayer 所在的 MediaServer 进程、应用进程),核心能力:- 持有服务端的 Binder 对象(通过
defaultServiceManager()->getService("media.extractor")获取); - 将客户端的本地方法调用(如
createExtractor)序列化为 Binder 数据,转发给服务端(BnMediaExtractorService/MediaExtractorService); - 接收服务端的返回数据,反序列化为本地对象(如
IMediaExtractor)并返回给客户端调用者(如 NuPlayer::GenericSource)。
- 持有服务端的 Binder 对象(通过
- 关键特性:客户端无需关心跨进程细节,调用此类方法与调用本地方法完全一致,由其自动完成 “本地→跨进程→服务端” 的转发。
三、四层关系总览(一张图讲清)
plaintext
┌─────────────────────────────────────────────────────────┐
│ 根接口:IMediaExtractorService(AIDL生成,纯虚方法规范) │
├─────────────────────┬─────────────────────────────────┤
│ 继承 │ 继承 │
├─────────────────────▼─────────────────────────────────┤
│ BnMediaExtractorService(AIDL生成,服务端Binder骨架) │
├─────────────────────┤ │
│ 继承 │ │
├─────────────────────▼─────────────────────────────────┤
│ MediaExtractorService(手动实现,实际业务逻辑) │
│ (运行在media.extractor进程,注册到ServiceManager) │
├─────────────────────────────────────────────────────────┤
│ BpMediaExtractorService(AIDL生成,客户端Binder代理) │
│ (运行在调用进程,持有服务端Binder对象,转发调用) │
└─────────────────────────────────────────────────────────┘
核心关联一句话:IMediaExtractorService是所有类的方法标准,Bn/BpMediaExtractorService是 AIDL 自动生成的跨进程通信骨架(服务端 / 客户端),MediaExtractorService是继承 Bn 并实现实际业务的最终服务类,也是media.extractor服务的实际载体。
四、代码层面的生成与实现(关键文件)
结合 Android AOSP 源码,明确四个类的生成文件、实现文件、版本差异,贴合你关注的 Android 9/10+:
| 类名 | 生成 / 实现方式 | 核心文件路径(Android 10+) | Android 9 版本差异 |
|---|---|---|---|
| IMediaExtractorService | AIDL 自动生成 | frameworks/av/media/libmedia/IMediaExtractorService.h | 路径一致,方法稍少 |
| BnMediaExtractorService | AIDL 自动生成 | frameworks/av/media/libmedia/IMediaExtractorService.cpp | 路径一致,内嵌在 IMediaExtractorService.cpp |
| BpMediaExtractorService | AIDL 自动生成 | frameworks/av/media/libmedia/IMediaExtractorService.cpp | 路径一致,内嵌在 IMediaExtractorService.cpp |
| MediaExtractorService | 手动实现 | frameworks/av/media/extractors/MediaExtractorService.cpp | 路径一致,未独立为 media.extractor 进程,运行在 MediaServer |
关键版本细节:
- Android 10+:
MediaExtractorService运行在独立的media.extractor进程(由main_extractor_service.cpp启动并注册服务); - Android 9:无独立
media.extractor进程,MediaExtractorService运行在MediaServer 进程,但类的关系、实现逻辑与高版本完全一致。
五、实际跨进程调用链路(与你的代码关联)
结合你之前的代码 sp<IBinder> binder = defaultServiceManager()->getService(String16("media.extractor"));,完整的跨进程调用链路如下(以 NuPlayer 调用createExtractor创建 MediaExtractor 为例):
plaintext
【客户端:MediaServer进程(NuPlayer/GenericSource)】
1. 客户端通过ServiceManager获取`media.extractor`的Binder对象(IBinder);
2. 将IBinder对象封装为`BpMediaExtractorService`实例(客户端代理);
3. 客户端调用`bpService->createExtractor(...)`(本地方法);
4. `BpMediaExtractorService`将方法参数**序列化为Parcel数据**,通过Binder驱动转发给服务端;
【Binder驱动:进程间数据转发】
- 负责将客户端的Parcel数据转发到`media.extractor`进程,同时转发服务端的返回数据;
【服务端:media.extractor进程(Android 10+)】
1. `BnMediaExtractorService`接收Binder驱动的Parcel数据,**反序列化为原始参数**;
2. `BnMediaExtractorService`将请求转发给子类`MediaExtractorService`的`createExtractor`方法;
3. `MediaExtractorService`执行实际业务:创建MediaExtractor实例、设置数据源、返回IMediaExtractor接口;
4. `BnMediaExtractorService`将返回结果**序列化为Parcel数据**,通过Binder驱动返回给客户端;
【客户端:MediaServer进程】
1. `BpMediaExtractorService`接收返回的Parcel数据,**反序列化为IMediaExtractor实例**;
2. 将IMediaExtractor返回给NuPlayer/GenericSource,完成跨进程调用;
核心亮点:客户端(NuPlayer)全程无需关心跨进程细节,调用BpMediaExtractorService的方法与调用本地类完全一致,所有底层通信由 Binder 框架和 AIDL 生成的类自动完成。
六、与你之前关注的BnMediaSource的关联(补充)
你之前在 Android 9 中接触的BnMediaSource,与本次的BnMediaExtractorService遵循完全相同的 Binder 设计规则:
BnMediaSource由IMediaSource.aidl自动生成,是IMediaSource接口的 Binder 服务端基类;- Android 9 中 GenericSource 内嵌的匿名子类,本质是继承
BnMediaSource并实现实际业务的自定义类(与MediaExtractorService继承BnMediaExtractorService的逻辑一致); - 简单说:
BnMediaSource是音视频数据源的服务端基类,BnMediaExtractorService是解封装服务的服务端基类,二者都是 AIDL 生成的 Binder 服务端骨架。
核心总结
- 根接口:
IMediaExtractorService(AIDL 生成),定义media.extractor服务的跨进程方法,是所有类的方法标准; - 通信骨架:
Bn/BpMediaExtractorService(AIDL 生成),分别为 Binder 服务端 / 客户端基类,提供跨进程通信的底层骨架,无业务逻辑; - 实际实现:
MediaExtractorService(手动实现),继承BnMediaExtractorService,实现所有抽象方法,是media.extractor服务的实际业务核心,也是注册到 ServiceManager 的真实服务对象; - 进程分布:Android 10 + 中
Bn/MediaExtractorService运行在media.extractor进程,Bp运行在调用进程;Android 9 中均运行在 MediaServer 进程,关系不变; - 设计规范:该四层关系是 Android Binder 跨进程通信的标准设计,所有系统服务(如 media.player、audio)均遵循此规范。
更多推荐



所有评论(0)