近期將 Android Studio 升級至最新版本後,許多開發者發現原本在 build.gradle 中配置 sourceSets { main { jniLibs.srcDirs = ['libs'] } } 導入 .so 文件的方式失效。典型目錄結構為 main/jniLibs/armeabi/libvideoencoder.so,但構建過程中仍報找不到動態庫。
Android Gradle Plugin 3.0+ 版本對 NDK 集成進行了重大調整:
jniLibs.srcDirs 手動指定目錄src/main/jniLibs/<abi>/ 標準目錄下project/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── jniLibs/
│ │ │ │ ├── arm64-v8a/
│ │ │ │ ├── armeabi-v7a/
│ │ │ │ ├── x86/
│ │ │ │ └── x86_64/
│ │ │ │ └── libvideoencoder.so
移除 build.gradle 中的 sourceSets 配置,直接同步項目即可。
# CMakeLists.txt
add_library(videoencoder SHARED IMPORTED)
set_target_properties(videoencoder PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libvideoencoder.so)
target_link_libraries(native-lib videoencoder log)
在 build.gradle 中配置 externalNativeBuild.cmake.path,Gradle 會自動處理打包。
android {
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}
注意:路徑需指向 jniLibs 父目錄,而非具體 ABI 子目錄。
| Android Gradle Plugin | 推薦方式 | 備註 |
|---|---|---|
| 3.0 - 4.1 | 標準目錄 / CMake | sourceSets 仍可工作但會警告 |
| 4.2+ | CMake / ndk-build | sourceSets 可能完全失效 |
| 7.0+ | CMake 必須 | 全面轉向 CMake 集成 |
armeabi-v7a 而非 armeabi)debug 版本build.gradle 中聲明 android { defaultConfig { ndk { abiFilters 'armeabi-v7a', 'arm64-v8a' } } }構建 APK 後,使用 unzip -l app/build/outputs/apk/debug/app-debug.apk | grep .so 確認動態庫是否正確打包至 lib/<abi>/ 目錄。
現代 Android 開發強烈建議遷移至 CMake 管理原生庫,這不僅解決了導入問題,還能獲得更好的構建緩存、增量編譯和跨平台支持。若維護舊項目,請確保目錄結構符合最新規範,並逐步規劃遷移路線。