Android中framework层的cpp文件中调用native层c函数的方法

本文介绍了如何在Android项目的framework层中通过编辑Android.mk文件来添加动态链接库(.so)及对应的头文件路径。主要内容包括:如何指定本地共享库、设置C语言的包含路径,并在C++源文件中引入这些头文件及调用相应的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.在framework层中cpp文件所在的目录下的Android.mk中,加入:


1)LOCAL_SHARED_LIBRARIES:=  XX.so(加入c所在文件编译生成动态链接库.so文件)


2)LOCAL_C_INCLUDE  := $(TOP)/xx/xx


2.在cpp文件中直接包含头文件。#include "xx.h"


3.直接调用.h中的函数。

<think>我们之前已经讨论过,在Android系统中,Framework的MediaRecorder(Java/Kotlin API)通过JNI调用Libraries的原生代码。但需要明确的是,Libraries中并没有一个名为"MediaRecorder"的类直接对应,而是由多个模块协同工作,包括libmedia中的相关部分,以及更底的AudioFlinger服务等。 具体到录音功能: - 当使用**MediaRecorder**进行录音时,Framework的MediaRecorder最终会调用到Libraries的**StagefrightRecorder**(在libstagefright中)或类似实现(不同Android版本可能不同),而StagefrightRecorder内部会调用**AudioSource**(与AudioRecord相关)来获取音频数据。 - 但若开发者直接使用**AudioRecord**类,则是另一条路径:Framework的AudioRecord通过JNI调用Libraries的**AudioRecord**(C++类),直接与AudioFlinger交互获取原始PCM数据。 因此,针对问题:Framework的MediaRecorder在录音时,**既不是直接调用Libraries的MediaRecorder(因为Libraries没有同名类),也不是直接调用Libraries的AudioRecord**,而是通过调用Libraries的**StagefrightRecorder**,再由StagefrightRecorder内部创建并管理一个**AudioSource**对象(该对象封装了与AudioRecord底类似的功能)来获取音频数据。 ### 详细流程 1. **Framework**:`android.media.MediaRecorder.start()` 2. **JNI**:调用`android_media_MediaRecorder_start()`(在`android_media_MediaRecorder.cpp`中) 3. **Libraries**: - JNI函数调用`MediaRecorderClient::start()`(这是一个Binder客户端代理,通过IPC调用MediaPlayerService) - `MediaPlayerService`创建`StagefrightRecorder`实例并调用其`start()`方法。 4. **音频采集**: - `StagefrightRecorder::start()`内部根据配置创建音频源: ```cpp // StagefrightRecorder.cpp (简化) status_t StagefrightRecorder::start() { // 创建AudioSource sp<AudioSource> audioSource = new AudioSource(...); // 将audioSource连接到编码器 mWriter->addSource(audioSource); } ``` - `AudioSource`是`StagefrightRecorder`的内部组件,它通过`AudioRecord`底接口(`libaudioclient`)获取原始音频流。 ### 关键点 - **间接依赖AudioRecord**:虽然Framework的MediaRecorder不直接调用Libraries的AudioRecord,但底通过`AudioSource`(其实现基于`libaudioclient`的`AudioRecord`)获取数据。 - **为什么不用同名类?** Libraries没有"MediaRecorder"类,而是由`MediaRecorderClient`(代理)、`StagefrightRecorder`(功能实现)等共同完成。 ### 总结 Framework的`MediaRecorder`在录音时: 1. 通过JNI调用Native的媒体服务(如`MediaPlayerService`)。 2. 由`StagefrightRecorder`处理具体逻辑,它内部使用`AudioSource`(封装了类似`AudioRecord`的底音频采集功能)获取数据。 因此,**Framework的MediaRecorder依赖于Libraries的StagefrightRecorder(而非同名类),而StagefrightRecorder内部使用AudioSource,后者基于Libraries的AudioRecord实现**。 §§相关问题§§ 1. StagefrightRecorder在Android媒体框架中的主要作用是什么? 2. AudioSource和AudioRecord在底实现上有何区别与联系? 3. 为什么Android设计成MediaRecorder不直接调用AudioRecord而是通过StagefrightRecorder? 4. 使用MediaRecorder和直接使用AudioRecord在性能上有何差异? 5. MediaPlayerService在MediaRecorder的工作流程中扮演什么角色?</think>在Android系统中,Framework的`MediaRecorder`在录音功能实现上,**主要调用Libraries的`AudioRecord`而非直接调用同名类**。以下是具体协同机制: ### 关键调用关系 1. **Framework入口** `android.media.MediaRecorder`的Java/Kotlin API(如`start()`)是开发者直接调用的接口。 2. **JNI桥接** 通过`android_media_MediaRecorder.cpp`将调用转发到Native: ```cpp // JNI映射 static const JNINativeMethod gMethods[] = { {"_start", "()V", (void *)android_media_MediaRecorder_start} }; ``` 3. **Libraries核心调用** - **实际调用对象**:Framework最终调用`AudioRecord`(位于`libaudioclient`) - **调用路径**: ```mermaid graph LR A[MediaRecorder.start] --> B[JNI _start] B --> C[StagefrightRecorder::start] C --> D[创建AudioSource] D --> E[AudioSource::start] E --> F[AudioRecord::start] ``` 4. **音频数据流** `AudioRecord`直接与`AudioFlinger`服务交互,通过共享内存获取原始PCM数据: ```cpp // AudioSource.cpp status_t AudioSource::start() { mRecord->start(); // mRecord是AudioRecord对象 } ``` ### 为什么不是同名类? - **Libraries无直接对应类**: Android Native没有名为`MediaRecorder`的类,功能由多个组件协作: - `StagefrightRecorder`:处理媒体封装(如MP4/3GP) - `AudioSource`:音频采集接口 - `AudioRecord`:实际音频流处理核心 - **设计分离原因**: 1. **功能解耦**: - `MediaRecorder`处理高逻辑(格式封装/状态管理) - `AudioRecord`专注底音频流(低延迟/硬件交互) 2. **复用性**: `AudioRecord`可被`MediaRecorder`和`AudioRecord` API共用 3. **性能优化**: 直接操作音频流避免多封装开销 ### 工作流程示例 ```plaintext 应用 │ ▼ Framework MediaRecorder (Java) │ ▼ (JNI) StagefrightRecorder (C++) → 配置封装格式 │ ▼ 创建AudioSource │ ▼ 调用AudioRecord (C++) → 从AudioFlinger获取PCM │ ▼ 编码器 → 写入文件 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值