开发环境配置:Android Studio 工程、CMakeLists 与 build.gradle 依赖、API 级别要求
本章完成《Surface 与 MediaCodec 边界实操指南》所需的开发环境搭建。核心目标:创建 Android Studio 工程,集成 CMakeLists 编译原生代码,在 build.gradle 中配置 MediaCodec/Surface 相关依赖,并设定最低 API 级别以保证接口可用。以下步骤适用于 Android Studio Arctic Fox 及更高版本。
4.1 工程结构与编译链总览
下图展示 Android 项目各模块、依赖及编译链的关系。灰色虚线框代表可选模块,实线框为必选。箭头标识依赖流向。
4.2 创建工程与配置 CMakeLists
在 Android Studio 中通过 New Project → Native C++ 模板创建。模板会自动生成 CMakeLists.txt 和 native-lib.cpp。以下为适应 MediaCodec/Surface 操作的标准化 CMakeLists.txt 示例:
cmake_minimum_required(VERSION 3.18.1)
project("media-surface-bridge")
# 设置 C++ 标准为 C++17,启用 exceptions / rtti
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# 添加 native 库
add_library(
native-media
SHARED
native-lib.cpp
# 后续可添加更多 .cpp 文件
)
# 链接系统库(mediandk 提供 AMediaCodec API)
target_link_libraries(
native-media
android
mediandk # 必须!用于 AMediaCodec、AMediaFormat
log # 可选,用于 __android_log_print
jnigraphics # 可选,用于直接操作 Bitmap 像素
)
📌 CMakeLists.txt 中不能遗漏
mediandk 库,否则编译通过但运行时报 UnsatisfiedLinkError。4.3 build.gradle 依赖与 API 级别要求
Module 级 build.gradle 需配置 externalNativeBuild 以及最低/目标 SDK 版本。以下为关键片段:
android {
compileSdk 34 // 使用最新的 API 定义
ndkVersion "25.2.9519653" // 建议 NDK r25 及以上
defaultConfig {
minSdk 21 // MediaCodec 自 API 16 提供,但 Surface 输入需 API 21+
targetSdk 34
externalNativeBuild {
cmake {
cppFlags "-std=c++17 -O2"
// 指定 ABI 过滤,避免不必要的构建
abiFilters "arm64-v8a", "x86_64"
}
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
version "3.22.1" // 与 local.properties 或 SDK Manager 安装版本匹配
}
}
}
dependencies {
// 无需额外第三方库——MediaCodec / Surface 均为平台 API
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}
⚠️ 若
minSdk 低于 21,编译可通过但运行时 MediaCodec 的 createInputSurface() (API 21 引入) 会抛出 UnsupportedOperationException。Surface 输入为 API 23 完善,强烈建议 minSdk ≥ 23 实测。4.4 API 级别关键对照表
不同 MediaCodec 与 Surface 操作所需的最低 API 级别如下,配置时须保证 minSdk 不低于对应值:
| 功能/接口 | 最低 API | 备注 |
|---|---|---|
| MediaCodec 基础编解码 | 16 | 同步模式可用 |
| createInputSurface()(Surface 输入) | 21 | 必须 minSdk ≥ 21 |
| setInputSurface()(MediaMuxer 关联) | 23 | 配合 MediaMuxer 时强制要求 |
| getInputSurface()(获取 Surface 给 Camera) | 23 | 实时输入场景常用 |
| AMediaCodec NDK 接口 | 21 | 从 libmediandk.so 获取 |
| SurfaceView / TextureView 硬件加速 | 14 | 但 Surface 输入至少 21 |
4.5 调试验证与常见错误修正
配置完成后执行 Build → Make Project。若遇到以下问题,按表格排查:
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
Unresolved inclusion: <media/NdkMediaCodec.h> |
CMakeLists 未链接 mediandk |
检查 target_link_libraries 中是否包含 mediandk |
undefined reference to 'AMediaCodec_createDecoderByType' |
NDK 版本过旧或未链接 libmediandk | 升级 NDK 至 r23+,并确认 CMakeLists 正确链接 |
Could not find method externalNativeBuild() |
Android Gradle Plugin 版本低于 4.0 | 更新 AGP 至 7.0+,或改用 externalNativeBuild { cmake {...} } 语法 |
编译成功但 native-lib 未找到 |
ABI 过滤排除了目标设备架构 | abiFilters 中至少保留 arm64-v8a 或 armeabi-v7a |
💡 建议在
app/build.gradle 中同时设置 ndk { abiFilters "arm64-v8a", "x86_64" } 以加快模拟器调试;真机通常只需 arm64-v8a。