向您的項(xiàng)目添加 C 和 C++ 代碼
本文內(nèi)容
創(chuàng)建支持 C/C++ 的新項(xiàng)目
將 Gradle 關(guān)聯(lián)到您的原生庫(kù)
搭配使用Android Studio 2.2 或更高版本與Android Plugin for Gradle 版本 2.2.0 或更高版本時(shí),您可以將 C 和 C++ 代碼編譯到 Gradle 與 APK 一起封裝的原生庫(kù)中,將這類(lèi)代碼添加到您的應(yīng)用中。您的 Java 代碼隨后可以通過(guò) Java 原生接口 (JNI) 調(diào)用您的原生庫(kù)中的函數(shù)。如果您想要詳細(xì)了解如何使用 JNI 框架,請(qǐng)閱讀Android 的 JNI 提示。
Android Studio 用于構(gòu)建原生庫(kù)的默認(rèn)工具是 CMake。由于很多現(xiàn)有項(xiàng)目都使用構(gòu)建工具包編譯其原生代碼,Android Studio 還支持ndk-build。如果您想要將現(xiàn)有的 ndk-build 庫(kù)導(dǎo)入到您的 Android Studio 項(xiàng)目中,請(qǐng)參閱介紹如何配置 Gradle 以關(guān)聯(lián)到您的原生庫(kù)的部分。不過(guò),如果您在創(chuàng)建新的原生庫(kù),則應(yīng)使用 CMake。
本頁(yè)面介紹的信息可以幫助您使用所需構(gòu)建工具設(shè)置 Android Studio、創(chuàng)建或配置項(xiàng)目以支持 Android 上的原生代碼,以及構(gòu)建和運(yùn)行應(yīng)用。
注:如果您的現(xiàn)有項(xiàng)目使用已棄用的ndkCompile工具,則應(yīng)先打開(kāi)build.properties文件,并移除以下代碼行,然后再將 Gradle 關(guān)聯(lián)到您的原生庫(kù):
// Remove this line
android.useDeprecatedNdk = true
實(shí)驗(yàn)性 Gradle 的用戶注意事項(xiàng):如果您是以下任意一種情況,請(qǐng)考慮遷移到插件版本 2.2.0 或更高版本并使用 CMake 或 ndk-build 構(gòu)建原生庫(kù):您的原生項(xiàng)目已經(jīng)使用 CMake 或者 ndk-build;但是您想要使用穩(wěn)定版本的 Gradle 構(gòu)建系統(tǒng);或者您希望支持插件工具,例如CCache。否則,您可以繼續(xù)使用實(shí)驗(yàn)性版本的 Gradle 和 Android 插件。
下載 NDK 和構(gòu)建工具
要為您的應(yīng)用編譯和調(diào)試原生代碼,您需要以下組件:
Android 原生開(kāi)發(fā)工具包 (NDK):這套工具集允許您為 Android 使用 C 和 C++ 代碼,并提供眾多平臺(tái)庫(kù),讓您可以管理原生 Activity 和訪問(wèn)物理設(shè)備組件,例如傳感器和觸摸輸入。
CMake:一款外部構(gòu)建工具,可與 Gradle 搭配使用來(lái)構(gòu)建原生庫(kù)。如果您只計(jì)劃使用 ndk-build,則不需要此組件。
LLDB:一種調(diào)試程序,Android Studio 使用它來(lái)調(diào)試原生代碼。
您可以使用 SDK 管理器安裝這些組件:
在打開(kāi)的項(xiàng)目中,從菜單欄選擇Tools > Android > SDK Manager。
點(diǎn)擊SDK Tools標(biāo)簽。
選中LLDB、CMake和NDK旁的復(fù)選框,如圖 1 所示。
圖 1.從 SDK 管理器中安裝 LLDB、CMake 和 NDK。
點(diǎn)擊Apply,然后在彈出式對(duì)話框中點(diǎn)擊OK。
安裝完成后,點(diǎn)擊Finish,然后點(diǎn)擊OK。
創(chuàng)建支持 C/C++ 的新項(xiàng)目
創(chuàng)建支持原生代碼的項(xiàng)目與創(chuàng)建任何其他 Android Studio 項(xiàng)目類(lèi)似,不過(guò)前者還需要額外幾個(gè)步驟:
在向?qū)У腃onfigure your new project部分,選中Include C++ Support復(fù)選框。
點(diǎn)擊Next。
正常填寫(xiě)所有其他字段并完成向?qū)Ы酉聛?lái)的幾個(gè)部分。
在向?qū)У腃ustomize C++ Support部分,您可以使用下列選項(xiàng)自定義項(xiàng)目:
C++ Standard:使用下拉列表選擇您希望使用哪種 C++ 標(biāo)準(zhǔn)。選擇Toolchain Default會(huì)使用默認(rèn)的 CMake 設(shè)置。
Exceptions Support:如果您希望啟用對(duì) C++ 異常處理的支持,請(qǐng)選中此復(fù)選框。如果啟用此復(fù)選框,Android Studio 會(huì)將-fexceptions標(biāo)志添加到模塊級(jí)build.gradle文件的cppFlags中,Gradle 會(huì)將其傳遞到 CMake。
Runtime Type Information Support:如果您希望支持 RTTI,請(qǐng)選中此復(fù)選框。如果啟用此復(fù)選框,Android Studio 會(huì)將-frtti標(biāo)志添加到模塊級(jí)build.gradle文件的cppFlags中,Gradle 會(huì)將其傳遞到 CMake。
點(diǎn)擊Finish。
在 Android Studio 完成新項(xiàng)目的創(chuàng)建后,請(qǐng)從 IDE 左側(cè)打開(kāi)Project窗格并選擇Android視圖。如圖 2 中所示,Android Studio 將添加cpp和External Build Files組:
圖 2.您的原生源文件和外部構(gòu)建腳本的 Android 視圖組。
注:此視圖無(wú)法反映磁盤(pán)上的實(shí)際文件層次結(jié)構(gòu),而是將相似文件分到一組中,簡(jiǎn)化項(xiàng)目導(dǎo)航。
在cpp組中,您可以找到屬于項(xiàng)目的所有原生源文件、標(biāo)頭和預(yù)構(gòu)建庫(kù)。對(duì)于新項(xiàng)目,Android Studio 會(huì)創(chuàng)建一個(gè)示例 C++ 源文件native-lib.cpp,并將其置于應(yīng)用模塊的src/main/cpp/目錄中。本示例代碼提供了一個(gè)簡(jiǎn)單的 C++ 函數(shù)stringFromJNI(),此函數(shù)可以返回字符串“Hello from C++”。要了解如何向項(xiàng)目添加其他源文件,請(qǐng)參閱介紹如何創(chuàng)建新的原生源文件的部分。
在External Build Files組中,您可以找到 CMake 或 ndk-build 的構(gòu)建腳本。與build.gradle文件指示 Gradle 如何構(gòu)建應(yīng)用一樣,CMake 和 ndk-build 需要一個(gè)構(gòu)建腳本來(lái)了解如何構(gòu)建您的原生庫(kù)。對(duì)于新項(xiàng)目,Android Studio 會(huì)創(chuàng)建一個(gè) CMake 構(gòu)建腳本CMakeLists.txt,并將其置于模塊的根目錄中。要詳細(xì)了解此構(gòu)建腳本的內(nèi)容,請(qǐng)參閱介紹如何創(chuàng)建 Cmake 構(gòu)建腳本的部分。
構(gòu)建和運(yùn)行示例應(yīng)用
點(diǎn)擊Run
后,Android Studio 將在您的 Android 設(shè)備或者模擬器上構(gòu)建并啟動(dòng)一個(gè)顯示文字“Hello from C++”的應(yīng)用。下面的概覽介紹了構(gòu)建和運(yùn)行示例應(yīng)用時(shí)會(huì)發(fā)生的事件:
Gradle 調(diào)用您的外部構(gòu)建腳本CMakeLists.txt。
CMake 按照構(gòu)建腳本中的命令將 C++ 源文件native-lib.cpp編譯到共享的對(duì)象庫(kù)中,并命名為libnative-lib.so,Gradle 隨后會(huì)將其封裝到 APK 中。
運(yùn)行時(shí),應(yīng)用的MainActivity會(huì)使用System.loadLibrary()加載原生庫(kù)。現(xiàn)在,應(yīng)用可以使用庫(kù)的原生函數(shù)stringFromJNI()。
MainActivity.onCreate()調(diào)用stringFromJNI(),這將返回“Hello from C++”并使用這些文字更新TextView。
注:Instant Run與使用原生代碼的項(xiàng)目不兼容。Android Studio 會(huì)自動(dòng)停用此功能。
如果您想要驗(yàn)證 Gradle 是否已將原生庫(kù)封裝到 APK 中,可以使用APK 分析器:
選擇Build > Analyze APK。
從app/build/outputs/apk/目錄中選擇 APK 并點(diǎn)擊OK。
如圖 3 中所示,您會(huì)在 APK 分析器窗口的lib//下看到libnative-lib.so。
圖 3.使用 APK 分析器定位原生庫(kù)。
提示:如果您想要試驗(yàn)使用原生代碼的其他 Android 應(yīng)用,請(qǐng)點(diǎn)擊File > New > Import Sample并從Ndk列表中選擇示例項(xiàng)目。
向現(xiàn)有項(xiàng)目添加 C/C++ 代碼
如果您希望向現(xiàn)有項(xiàng)目添加原生代碼,請(qǐng)執(zhí)行以下步驟:
創(chuàng)建新的原生源文件并將其添加到您的 Android Studio 項(xiàng)目中。
如果您已經(jīng)擁有原生代碼或想要導(dǎo)入預(yù)構(gòu)建的原生庫(kù),則可以跳過(guò)此步驟。
創(chuàng)建 CMake 構(gòu)建腳本,將您的原生源代碼構(gòu)建到庫(kù)中。如果導(dǎo)入和關(guān)聯(lián)預(yù)構(gòu)建庫(kù)或平臺(tái)庫(kù),您也需要此構(gòu)建腳本。
如果您的現(xiàn)有原生庫(kù)已經(jīng)擁有CMakeLists.txt構(gòu)建腳本或者使用 ndk-build 并包含Android.mk構(gòu)建腳本,則可以跳過(guò)此步驟。
提供一個(gè)指向您的 CMake 或 ndk-build 腳本文件的路徑,將 Gradle 關(guān)聯(lián)到您的原生庫(kù)。Gradle 使用構(gòu)建腳本將源代碼導(dǎo)入您的 Android Studio 項(xiàng)目并將原生庫(kù)(SO 文件)封裝到 APK 中。
配置完項(xiàng)目后,您可以使用JNI 框架從 Java 代碼中訪問(wèn)您的原生函數(shù)。要構(gòu)建和運(yùn)行應(yīng)用,只需點(diǎn)擊Run
。Gradle 會(huì)以依賴(lài)項(xiàng)的形式添加您的外部原生構(gòu)建流程,用于編譯、構(gòu)建原生庫(kù)并將其隨 APK 一起封裝。
創(chuàng)建新的原生源文件
要在應(yīng)用模塊的主源代碼集中創(chuàng)建一個(gè)包含新建原生源文件的cpp/目錄,請(qǐng)按以下步驟操作:
從 IDE 的左側(cè)打開(kāi)Project窗格并從下拉菜單中選擇Project視圖。
導(dǎo)航到您的模塊> src,右鍵點(diǎn)擊main目錄,然后選擇New > Directory。
為目錄輸入一個(gè)名稱(chēng)(例如cpp)并點(diǎn)擊OK。
右鍵點(diǎn)擊您剛剛創(chuàng)建的目錄,然后選擇New > C/C++ Source File。
為您的源文件輸入一個(gè)名稱(chēng),例如native-lib。
從Type下拉菜單中,為您的源文件選擇文件擴(kuò)展名,例如.cpp。
點(diǎn)擊Edit File Types
,您可以向下拉菜單中添加其他文件類(lèi)型,例如.cxx或.hxx。在彈出的C/C++對(duì)話框中,從Source Extension和Header Extension下拉菜單中選擇另一個(gè)文件擴(kuò)展名,然后點(diǎn)擊OK。
如果您還希望創(chuàng)建一個(gè)標(biāo)頭文件,請(qǐng)選中Create an associated header復(fù)選框。
點(diǎn)擊OK。
創(chuàng)建 CMake 構(gòu)建腳本
如果您的原生源文件還沒(méi)有 CMake 構(gòu)建腳本,則您需要自行創(chuàng)建一個(gè)并包含適當(dāng)?shù)?CMake 命令。CMake 構(gòu)建腳本是一個(gè)純文本文件,您必須將其命名為CMakeLists.txt。本部分介紹了您應(yīng)包含到構(gòu)建腳本中的一些基本命令,用于在創(chuàng)建原生庫(kù)時(shí)指示 CMake 應(yīng)使用哪些源文件。
注:如果您的項(xiàng)目使用 ndk-build,則不需要?jiǎng)?chuàng)建 CMake 構(gòu)建腳本。提供一個(gè)指向您的Android.mk文件的路徑,將 Gradle 關(guān)聯(lián)到您的原生庫(kù)。
要?jiǎng)?chuàng)建一個(gè)可以用作 CMake 構(gòu)建腳本的純文本文件,請(qǐng)按以下步驟操作:
從 IDE 的左側(cè)打開(kāi)Project窗格并從下拉菜單中選擇Project視圖。
右鍵點(diǎn)擊您的模塊的根目錄并選擇New > File。
注:您可以在所需的任意位置創(chuàng)建構(gòu)建腳本。不過(guò),在配置構(gòu)建腳本時(shí),原生源文件和庫(kù)的路徑將與構(gòu)建腳本的位置相關(guān)。
輸入“CMakeLists.txt”作為文件名并點(diǎn)擊OK。
現(xiàn)在,您可以添加 CMake 命令,對(duì)您的構(gòu)建腳本進(jìn)行配置。要指示 CMake 從原生源代碼創(chuàng)建一個(gè)原生庫(kù),請(qǐng)將cmake_minimum_required()和add_library()命令添加到您的構(gòu)建腳本中:
# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.
cmake_minimum_required(VERSION 3.4.1)
# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.
add_library( # Specifies the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
使用add_library()向您的 CMake 構(gòu)建腳本添加源文件或庫(kù)時(shí),Android Studio 還會(huì)在您同步項(xiàng)目后在Project視圖下顯示關(guān)聯(lián)的標(biāo)頭文件。不過(guò),為了確保 CMake 可以在編譯時(shí)定位您的標(biāo)頭文件,您需要將include_directories()命令添加到 CMake 構(gòu)建腳本中并指定標(biāo)頭的路徑:
add_library(...)
# Specifies a path to native header files.
include_directories(src/main/cpp/include/)
CMake 使用以下規(guī)范來(lái)為庫(kù)文件命名:
lib庫(kù)名稱(chēng).so
例如,如果您在構(gòu)建腳本中指定“native-lib”作為共享庫(kù)的名稱(chēng),CMake 將創(chuàng)建一個(gè)名稱(chēng)為libnative-lib.so的文件。不過(guò),在 Java 代碼中加載此庫(kù)時(shí),請(qǐng)使用您在 CMake 構(gòu)建腳本中指定的名稱(chēng):
static {
????System.loadLibrary(“native-lib”);
}
注:如果您在 CMake 構(gòu)建腳本中重命名或移除某個(gè)庫(kù),您需要先清理項(xiàng)目,Gradle 隨后才會(huì)應(yīng)用更改或者從 APK 中移除舊版本的庫(kù)。要清理項(xiàng)目,請(qǐng)從菜單欄中選擇Build > Clean Project。
Android Studio 會(huì)自動(dòng)將源文件和標(biāo)頭添加到Project窗格的cpp組中。使用多個(gè)add_library()命令,您可以為 CMake 定義要從其他源文件構(gòu)建的更多庫(kù)。
添加 NDK API
Android NDK 提供了一套實(shí)用的原生 API 和庫(kù)。通過(guò)將NDK 庫(kù)包含到項(xiàng)目的CMakeLists.txt腳本文件中,您可以使用這些 API 中的任意一種。
預(yù)構(gòu)建的 NDK 庫(kù)已經(jīng)存在于 Android 平臺(tái)上,因此,您無(wú)需再構(gòu)建或?qū)⑵浞庋b到 APK 中。由于 NDK 庫(kù)已經(jīng)是 CMake 搜索路徑的一部分,您甚至不需要在您的本地 NDK 安裝中指定庫(kù)的位置 - 只需要向 CMake 提供您希望使用的庫(kù)的名稱(chēng),并將其關(guān)聯(lián)到您自己的原生庫(kù)。
將find_library()命令添加到您的 CMake 構(gòu)建腳本中以定位 NDK 庫(kù),并將其路徑存儲(chǔ)為一個(gè)變量。您可以使用此變量在構(gòu)建腳本的其他部分引用 NDK 庫(kù)。以下示例可以定位Android 特定的日志支持庫(kù)并將其路徑存儲(chǔ)在log-lib中:
find_library( # Defines the name of the path variable that stores the
# location of the NDK library.
log-lib
# Specifies the name of the NDK library that
# CMake needs to locate.
log )
為了確保您的原生庫(kù)可以在log庫(kù)中調(diào)用函數(shù),您需要使用 CMake 構(gòu)建腳本中的target_link_libraries()命令關(guān)聯(lián)庫(kù):
find_library(...)
# Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the log library to the target library.
${log-lib} )
NDK 還以源代碼的形式包含一些庫(kù),您在構(gòu)建和關(guān)聯(lián)到您的原生庫(kù)時(shí)需要使用這些代碼。您可以使用 CMake 構(gòu)建腳本中的add_library()命令,將源代碼編譯到原生庫(kù)中。要提供本地 NDK 庫(kù)的路徑,您可以使用ANDROID_NDK路徑變量,Android Studio 會(huì)自動(dòng)為您定義此變量。
以下命令可以指示 CMake 構(gòu)建android_native_app_glue.c,后者會(huì)將NativeActivity生命周期事件和觸摸輸入置于靜態(tài)庫(kù)中并將靜態(tài)庫(kù)關(guān)聯(lián)到native-lib:
add_library( app-glue
STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
# You need to link static libraries against your shared native library.
target_link_libraries( native-lib app-glue ${log-lib} )
添加其他預(yù)構(gòu)建庫(kù)
添加預(yù)構(gòu)建庫(kù)與為 CMake 指定要構(gòu)建的另一個(gè)原生庫(kù)類(lèi)似。不過(guò),由于庫(kù)已經(jīng)預(yù)先構(gòu)建,您需要使用IMPORTED標(biāo)志告知 CMake 您只希望將庫(kù)導(dǎo)入到項(xiàng)目中:
add_library( imported-lib
SHARED
IMPORTED )
然后,您需要使用set_target_properties()命令指定庫(kù)的路徑,如下所示。
某些庫(kù)為特定的 CPU 架構(gòu)(或應(yīng)用二進(jìn)制接口 (ABI))提供了單獨(dú)的軟件包,并將其組織到單獨(dú)的目錄中。此方法既有助于庫(kù)充分利用特定的 CPU 架構(gòu),又能讓您僅使用所需的庫(kù)版本。要向 CMake 構(gòu)建腳本中添加庫(kù)的多個(gè) ABI 版本,而不必為庫(kù)的每個(gè)版本編寫(xiě)多個(gè)命令,您可以使用ANDROID_ABI路徑變量。此變量使用NDK 支持的一組默認(rèn) ABI,或者您手動(dòng)配置 Gradle而讓其使用的一組經(jīng)過(guò)篩選的 ABI。例如:
add_library(...)
set_target_properties( # Specifies the target library.
imported-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
imported-lib/src/${ANDROID_ABI}/libimported-lib.so )
為了確保 CMake 可以在編譯時(shí)定位您的標(biāo)頭文件,您需要使用include_directories()命令,并包含標(biāo)頭文件的路徑:
include_directories( imported-lib/include/ )
注:如果您希望封裝一個(gè)并不是構(gòu)建時(shí)依賴(lài)項(xiàng)的預(yù)構(gòu)建庫(kù)(例如在添加屬于imported-lib依賴(lài)項(xiàng)的預(yù)構(gòu)建庫(kù)時(shí)),則不需要執(zhí)行以下說(shuō)明來(lái)關(guān)聯(lián)庫(kù)。
要將預(yù)構(gòu)建庫(kù)關(guān)聯(lián)到您自己的原生庫(kù),請(qǐng)將其添加到 CMake 構(gòu)建腳本的target_link_libraries()命令中:
target_link_libraries( native-lib imported-lib app-glue ${log-lib} )
在您構(gòu)建應(yīng)用時(shí),Gradle 會(huì)自動(dòng)將導(dǎo)入的庫(kù)封裝到 APK 中。您可以使用APK 分析器驗(yàn)證 Gradle 將哪些庫(kù)封裝到您的 APK 中。如需了解有關(guān) CMake 命令的詳細(xì)信息,請(qǐng)參閱CMake 文檔。
將 Gradle 關(guān)聯(lián)到您的原生庫(kù)
要將 Gradle 關(guān)聯(lián)到您的原生庫(kù),您需要提供一個(gè)指向 CMake 或 ndk-build 腳本文件的路徑。在您構(gòu)建應(yīng)用時(shí),Gradle 會(huì)以依賴(lài)項(xiàng)的形式運(yùn)行 CMake 或 ndk-build,并將共享的庫(kù)封裝到您的 APK 中。Gradle 還使用構(gòu)建腳本來(lái)了解要將哪些文件添加到您的 Android Studio 項(xiàng)目中,以便您可以從Project窗口訪問(wèn)這些文件。如果您的原生源文件沒(méi)有構(gòu)建腳本,則需要先創(chuàng)建 CMake 構(gòu)建腳本,然后再繼續(xù)。
將 Gradle 關(guān)聯(lián)到原生項(xiàng)目后,Android Studio 會(huì)更新Project窗格以在cpp組中顯示您的源文件和原生庫(kù),在External Build Files組中顯示您的外部構(gòu)建腳本。
注:更改 Gradle 配置時(shí),請(qǐng)確保通過(guò)點(diǎn)擊工具欄中的Sync Project
應(yīng)用更改。此外,如果在將 CMake 或 ndk-build 腳本文件關(guān)聯(lián)到 Gradle 后再對(duì)其進(jìn)行更改,您應(yīng)當(dāng)從菜單欄中選擇Build > Refresh Linked C++ Projects,將 Android Studio 與您的更改同步。
使用 Android Studio UI
您可以使用 Android Studio UI 將 Gradle 關(guān)聯(lián)到外部 CMake 或 ndk-build 項(xiàng)目:
從 IDE 左側(cè)打開(kāi)Project窗格并選擇Android視圖。
右鍵點(diǎn)擊您想要關(guān)聯(lián)到原生庫(kù)的模塊(例如app模塊),并從菜單中選擇Link C++ Project with Gradle。您應(yīng)看到一個(gè)如圖 4 所示的對(duì)話框。
從下拉菜單中,選擇CMake或ndk-build。
如果您選擇CMake,請(qǐng)使用Project Path旁的字段為您的外部 CMake 項(xiàng)目指定CMakeLists.txt腳本文件。
如果您選擇ndk-build,請(qǐng)使用Project Path旁的字段為您的外部 ndk-build 項(xiàng)目指定Android.mk腳本文件。如果Application.mk文件與您的Android.mk文件位于相同目錄下,Android Studio 也會(huì)包含此文件。
圖 4.使用 Android Studio 對(duì)話框關(guān)聯(lián)外部 C++ 項(xiàng)目。
點(diǎn)擊OK。
手動(dòng)配置 Gradle
要手動(dòng)配置 Gradle 以關(guān)聯(lián)到您的原生庫(kù),您需要將externalNativeBuild {}塊添加到模塊級(jí)build.gradle文件中,并使用cmake {}或ndkBuild {}對(duì)其進(jìn)行配置:
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"
????????}
????}
}
注:如果您想要將 Gradle 關(guān)聯(lián)到現(xiàn)有 ndk-build 項(xiàng)目,請(qǐng)使用ndkBuild {}塊而不是cmake {},并提供Android.mk文件的相對(duì)路徑。如果Application.mk文件與您的Android.mk文件位于相同目錄下,Gradle 也會(huì)包含此文件。
指定可選配置
您可以在模塊級(jí)build.gradle文件的defaultConfig {}塊中配置另一個(gè)externalNativeBuild {}塊,為 CMake 或 ndk-build 指定可選參數(shù)和標(biāo)志。與defaultConfig {}塊中的其他屬性類(lèi)似,您也可以在構(gòu)建配置中為每個(gè)產(chǎn)品風(fēng)味重寫(xiě)這些屬性。
例如,如果您的 CMake 或 ndk-build 項(xiàng)目定義多個(gè)原生庫(kù),您可以使用targets屬性?xún)H為給定產(chǎn)品風(fēng)味構(gòu)建和封裝這些庫(kù)中的一部分。以下代碼示例說(shuō)明了您可以配置的部分屬性:
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 ndkBuild {}
????????????cmake {
???????????????// Passes optional arguments to CMake.
????????????????arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
????????????????// Sets optional flags for the C compiler.
????????????????cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
????????????????// Sets a flag to enable format macro constants for the C++ compiler.
????????????????cppFlags "-D__STDC_FORMAT_MACROS"
????????????}
????????}
????}
????buildTypes {...}
????productFlavors {
????...
????demo {
????????...
????????externalNativeBuild {
????????????cmake {
????????????????...
????????????????// Specifies which native libraries to build and package for this
????????????????// product flavor. If you don't configure this property, Gradle
????????????????// builds and packages all shared object libraries that you define
????????????????// in your CMake or ndk-build project.
????????????????targets "native-lib-demo"
????????????}
????????}
????}
????paid {
????????...
????????externalNativeBuild {
????????????cmake {
????????????????...
????????????????targets "native-lib-paid"
????????????}
????????}
????}
}
// Use this block to link Gradle to your CMake or ndk-build script.
externalNativeBuild {
????cmake {...}
????// or ndkBuild {...}
????}
}
要詳細(xì)了解配置產(chǎn)品風(fēng)味和構(gòu)建變體,請(qǐng)參閱配置構(gòu)建變體。如需了解您可以使用arguments屬性為 CMake 配置的變量列表,請(qǐng)參閱使用 CMake 變量。
指定 ABI
默認(rèn)情況下,Gradle 會(huì)針對(duì)NDK 支持的 ABI將您的原生庫(kù)構(gòu)建到單獨(dú)的.so文件中,并將其全部封裝到您的 APK 中。如果您希望 Gradle 僅構(gòu)建和封裝原生庫(kù)的特定 ABI 配置,您可以在模塊級(jí)build.gradle文件中使用ndk.abiFilters標(biāo)志指定這些配置,如下所示:
android {
????...
????defaultConfig {
????????...
????????externalNativeBuild {
????????????cmake {...}
????????????// or ndkBuild {...}
????????}
????????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(如上所示),因?yàn)樗鼤?huì)指示 Gradle 構(gòu)建和封裝原生庫(kù)的這些版本。不過(guò),如果您希望控制 Gradle 應(yīng)當(dāng)構(gòu)建的配置,并獨(dú)立于您希望其封裝到 APK 中的配置,請(qǐng)?jiān)赿efaultConfig.externalNativeBuild.cmake {}塊(或defaultConfig.externalNativeBuild.ndkBuild {}塊中)配置另一個(gè)abiFilters標(biāo)志。Gradle 會(huì)構(gòu)建這些 ABI 配置,不過(guò)僅會(huì)封裝您在defaultConfig.ndk{}塊中指定的配置。
為了進(jìn)一步降低 APK 的大小,請(qǐng)考慮配置 ABI APK 拆分,而不是創(chuàng)建一個(gè)包含原生庫(kù)所有版本的大型 APK,Gradle 會(huì)為您想要支持的每個(gè) ABI 創(chuàng)建單獨(dú)的 APK,并且僅封裝每個(gè) ABI 需要的文件。如果您配置 ABI 拆分,但沒(méi)有像上面的代碼示例一樣指定abiFilters標(biāo)志,Gradle 會(huì)構(gòu)建原生庫(kù)的所有受支持 ABI 版本,不過(guò)僅會(huì)封裝您在 ABI 拆分配置中指定的版本。為了避免構(gòu)建您不想要的原生庫(kù)版本,請(qǐng)為abiFilters標(biāo)志和 ABI 拆分配置提供相同的 ABI 列表。