Android Studio 如何關(guān)聯(lián) Gradle
前面的小節(jié)我們學習了如何配置 CMake。本小節(jié)學習如何把原生庫和 Gradle 構(gòu)建關(guān)聯(lián)起來。
1. 概述
如需添加我們的原生庫項目作為 Gradle 構(gòu)建依賴項,我們需要向 Gradle 提供 CMake 或 ndk-build 腳本文件的路徑。當我們構(gòu)建應(yīng)用時,Gradle 會運行 CMake 或 ndk-build,并將共享的庫打包到我們的 APK 中。
Gradle 還會使用構(gòu)建腳本來了解要將哪些文件添加到我們的 Android Studio 項目中,以便我們可以從 Project 窗口訪問這些文件。如果我們沒有原生源代碼文件的構(gòu)建腳本,則需要先創(chuàng)建 CMake 構(gòu)建腳本,然后再繼續(xù)。
Android 項目中的每個模塊只能關(guān)聯(lián)到一個 CMake 或 ndk-build 腳本文件。例如,如果我們想要構(gòu)建并打包來自多個 CMake 項目的輸出,就需要使用一個 CMakeLists.txt 文件作為頂級 CMake 構(gòu)建腳本(然后將 Gradle 關(guān)聯(lián)到該腳本),并添加其他 CMake 項目作為該構(gòu)建腳本的依賴項。同樣,如果我們使用的是 ndk-build,則可以在頂級 Android.mk 腳本文件中包含其他 Makefile。
2. 通過界面配置
我們可以使用 Android Studio 界面將 Gradle 關(guān)聯(lián)到外部 CMake 或 ndk-build 項目:
-
從 IDE 左側(cè)打開 Project 窗格,然后選擇 Android 視圖。
-
右鍵點擊我們想要關(guān)聯(lián)到原生庫的模塊(例如 app 模塊),然后從菜單中選擇 Link C++ Project with Gradle。
-
從下拉菜單中,選擇 CMake 或 ndk-build。
-
如果選擇 CMake,請使用 Project Path 旁的字段為我們的外部 CMake 項目指定 CMakeLists.txt 腳本文件。
-
如果選擇 ndk-build,請使用 Project Path 旁的字段為我們的外部 ndk-build 項目指定
Android.mk
腳本文件。如果Application.mk
文件與我們的Android.mk
文件位于同一目錄下,Android Studio 也會包含此文件。
-
-
點擊 OK。
3. 通過手動配置
要手動配置 Gradle 以關(guān)聯(lián)到我們的原生庫,我們需要將 externalNativeBuild 塊添加到模塊級 build.gradle 文件中,并使用 cmake 或 ndkBuild 塊對其進行配置:
android {
...
defaultConfig {...}
buildTypes {...}
// Encapsulates your external native build configurations.
externalNativeBuild {
// Encapsulates your CMake build configurations.
cmake {
// Provides a relative path to your CMake build script.
path "CMakeLists.txt"
}
}
}
3.1 指定可選配置
我們可以在模塊級 build.gradle 文件的 defaultConfig 塊中配置另一個 externalNativeBuild 塊,為 CMake 或 ndk-build 指定可選參數(shù)和標記。與 defaultConfig 塊中的其他屬性類似,我們也可以在構(gòu)建配置中為每種產(chǎn)品特性重寫這些屬性。
例如,如果我們的 CMake 或 ndk-build 項目定義多個原生庫和可執(zhí)行文件,我們可以使用 targets 屬性為指定產(chǎn)品特性構(gòu)建和打包其中的部分工件。以下代碼示例說明了我們可以配置的部分屬性:
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake or ndk-build script.
externalNativeBuild {
// For ndk-build, instead use the ndkBuild block.
cmake {
// Passes optional arguments to CMake.
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
// Sets a flag to enable format macro constants for the C compiler.
cFlags "-D__STDC_FORMAT_MACROS"
// Sets optional flags for the C++ compiler.
cppFlags "-fexceptions", "-frtti"
}
}
}
buildTypes {...}
productFlavors {
...
demo {
...
externalNativeBuild {
cmake {
...
// Specifies which native libraries or executables to build and package
// for this product flavor. The following tells Gradle to build only the
// "native-lib-demo" and "my-executible-demo" outputs from the linked
// CMake project. If you don't configure this property, Gradle builds all
// executables and shared object libraries that you define in your CMake
// (or ndk-build) project. However, by default, Gradle packages only the
// shared libraries in your APK.
targets "native-lib-demo",
// You need to specify this executable and its sources in your CMakeLists.txt
// using the add_executable() command. However, building executables from your
// native sources is optional, and building native libraries to package into
// your APK satisfies most project requirements.
"my-executible-demo"
}
}
}
paid {
...
externalNativeBuild {
cmake {
...
targets "native-lib-paid",
"my-executible-paid"
}
}
}
}
// Use this block to link Gradle to your CMake or ndk-build script.
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
}
3.2 添加預(yù)構(gòu)建的原生庫
如果希望 Gradle 將預(yù)構(gòu)建的原生庫打包到我們的 APK 中,請修改默認的源代碼集配置,以添加預(yù)構(gòu)建 .so 文件所在的目錄,如下所示。請注意,若要添加關(guān)聯(lián)到 Gradle 的 CMake 構(gòu)建腳本的工件,則無需執(zhí)行此操作。
android {
...
sourceSets {
main {
jniLibs.srcDirs 'imported-lib/src/', 'more-imported-libs/src/'
}
}
}
3.3 指定 ABI
默認情況下,Gradle 會針對 NDK 支持的應(yīng)用二進制接口 (ABI) 將我們的原生庫構(gòu)建到單獨的 .so 文件中,并將這些文件全部打包到我們的 APK 中。如果希望 Gradle 僅構(gòu)建和打包原生庫的部分 ABI 配置,則可以在模塊級 build.gradle 文件中使用 ndk.abiFilters 標記指定這些配置,如下所示:
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
// Similar to other properties in the defaultConfig block,
// you can configure the ndk block for each product flavor
// in your build configuration.
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
'arm64-v8a'
}
}
buildTypes {...}
externalNativeBuild {...}
}
在大多數(shù)情況下,我們只需要在 ndk 塊中指定 abiFilters,因為它會指示 Gradle 構(gòu)建和打包原生庫的這些版本。但是,如果我們想控制 Gradle 應(yīng)當構(gòu)建的配置,而不依賴于我們希望其打包到 APK 中的配置,請在 defaultConfig.externalNativeBuild.cmake
塊(或 defaultConfig.externalNativeBuild.ndkBuild
塊)中配置另一個 abiFilters 標記。Gradle 會構(gòu)建這些 ABI 配置,但只會打包我們在 defaultConfig.ndk 塊中指定的配置。
4. 小結(jié)
本節(jié)課程我們主要學習了如何把原生庫和 Gradle 構(gòu)建關(guān)聯(lián)起來。本節(jié)課程的重點如下:
- 掌握如何添加 Gradle 關(guān)聯(lián)配置。