实验一. Android NDK之Hello World开发入门实验
术语解释
NDK
NDK(英语:native development kit,简称NDK)是一种基于原生程序接口的软件开发工具。通过此工具开发的程序直接以本地语言运行,而非虚拟机。因此只有java等基于虚拟机运行的语言的程序才会有原生开发工具包。
- NDK是一系列工具的集合
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。
- NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。
NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
- 那我们为什么要使用呢?
- 代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
- 可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
- 提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
- 便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
NDK提供了一份稳定、功能有限的 API 头文件声明Google 明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C 标准库(libc)、标准数学库(libm)、压缩库(libz)、Log 库(liblog)。
JNI
JNI(Java NativenInterface)是java与C/C++进行通信的一种技术,使用JNI技术,可以java调用C/C++的函数对象等等,Android中的Framework层与Native层就是采用的JNI技术。
我们知道,Android系统是基于linux开发,采用的是linux内核 ,Android APP开发大部分也要和系统打交道,只是Android FrameWork 帮我们处理了和系统相关的操作, 我们从Android 系统的分成结构可以看出,Android FrameWork是通过JNI与底层的C/C++库交互,例如:FreeType,OpenGL,SQLite,音视频等等。
如果我们程序也需要调用自己的C/C++函数库,就必须用到JNI/NDK开发。
Cmake
CMake 是个开源的跨平台自动化建构系统,它用配置文件控制建构过程(build process)的方式和Unix的Make相似,只是CMake的配置文件取名为CMakeLists.txt。Cmake并不直接建构出最终的软件,而是产生标准的建构档(如Unix的Makefile或Windows Visual C++的projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是CMake和SCons等其他类似系统的区别之处。CMake可以编译源代码、制做程序库、产生适配器(wrapper)、还可以用任意的顺序建构可执行文件。CMake支持in-place建构(二进档和源代码在同一个目录树中)和out-of-place建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake也支持静态与动态程序库的建构。
“CMake”这个名字是"cross platform make"的缩写。虽然名字中含有"make",但是CMake和Unix上常见的“make”系统是分开的,而且更为高级。
- Cmake的优势
- 可以直接的在C/C++代码中加入断点,进行调试
- java引用的C/C++中的方法,可以直接ctrl+左键进入
- 对于include的头文件,或者库,也可以直接的进入
- 不需要配置命令行操作,手动的生成头文件,不需要配置android.useDeprecatedNdk=true 属性使用 Android studio,你可以将 C 和 C++ 代码编译成 native library(即 .so文件),然后打包到你的 APK 中。你的 Java 代码可以通过 Java Native Interface(JNI)调用 native library 中的方法。
Android Studio 用于构建原生库的默认工具是 CMake。由于很多现有项目都使用构建工具包编译其原生代码,Android Studio 还支持 ndk-build。如果您想要将现有的ndk-build 库导入到您的 Android Studio 项目中,请参阅介绍如何配置 Gradle以关联到您的原生库的部分。不过,如果您在创建新的原生库,则应使用CMake。
本页面介绍的信息可以帮助您使用所需构建工具设置 Android Studio、创建或配置项目以支持 Android 上的原生代码,以及构建和运行应用。
注:要在 Android Studio 中使用 CMake 或者 ndk-build,你需要使用Android Studio 2.2 或更高的版本,同时需要配合使用 Android Plugin for Gradle 2.2.0 及以上的版本。
下载 NDK 和构建工具
要为您的应用编译和调试原生代码,您需要以下组件:
- Android 原生开发工具包 (NDK):这套工具集允许您为 Android 使用 C 和 C++ 代码,并提供众多平台库,让您可以管理原生 Activity 和访问物理设备组件,例如传感器和触摸输入。
- CMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。
- LLDB:一种调试程序,Android Studio 使用它来调试原生代码。
您可以使用 SDK 管理器安装这些组件:
- 在打开的项目中,从菜单栏选择 Tools > Android > SDK Manager。
- 点击 SDK Tools 标签。
选中 LLDB、CMake 和 NDK 旁的复选框,如图 1 所示。
图 1.从 SDK 管理器中安装 LLDB、CMake 和 NDK。
点击 Apply,然后在弹出式对话框中点击 OK。
- 安装完成后,点击 Finish,然后点击 OK。
创建支持 C/C++ 的新项目
创建支持原生代码的项目与创建任何其他 Android Studio 项目类似,不过前者还需要额外几个步骤:
- 在向导的 Configure your new project 部分,选中 Include C++ Support 复选框。
- 点击 Next。
- 正常填写所有其他字段并完成向导接下来的几个部分。
在向导的 Customize C++ Support 部分,您可以使用下列选项自定义项目:
- C++ Standard:使用下拉列表选择您希望使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置。
- Exceptions Support:如果您希望启用对 C++
异常处理的支持,请选中此复选框。如果启用此复选框,Android Studio
会将
-fexceptions
标志添加到模块级build.gradle
文件的cppFlags
中,Gradle 会将其传递到 CMake。 - Runtime Type Information Support:如果您希望支持
RTTI,请选中此复选框。如果启用此复选框,Android Studio 会将
-frtti
标志添加到模块级build.gradle
文件的cppFlags
中,Gradle 会将其传递到 CMake。
点击 Finish。
在 Android Studio 完成新项目的创建后,请从 IDE 左侧打开 Project 窗格并选择 Android 视图。如图 2 中所示,Android Studio 将添加 cpp 和 External Build Files 组:
图 2.您的原生源文件和外部构建脚本的 Android 视图组。
- 在 cpp组中,您可以找到属于项目的所有原生源文件、标头和预构建库。对于新项目,Android
Studio 会创建一个示例 C++ 源文件
native-lib.cpp
,并将其置于应用模块的src/main/cpp/
目录中。本示例代码提供了一个简单的C++函数stringFromJNI()
,此函数可以返回字符串“Hello from C++”。要了解如何向项目添加其他源文件,请参阅介绍如何创建新的原生源文件的部分。 - 在 External Build Files 组中,您可以找到 CMake 或 ndk-build
的构建脚本。与
build.gradle
文件指示 Gradle 如何构建应用一样,CMake 和 ndk-build 需要一个构建脚本来了解如何构建您的原生库。对于新项目,Android Studio 会创建一个 CMake 构建脚本CMakeLists.txt
,并将其置于模块的根目录中。要详细了解此构建脚本的内容,请参阅介绍如何创建 Cmake 构建脚本的部分。
手动添加native方法
上面主要介绍程序自动生成的代码,接下来自己动手写。 我们也可以在MainActivity中写一个native方法。
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
//手动添加native方法
public native String stringFromJNI2();
新方法stringFromJNI2()
有红色警告,将光标定位到该函数并按下alt+Enter键。会弹出如图3所示的下拉列表,选择Create function ...
选项
图 3.创建本地方法。
跳转到native-lib.cpp
会自动生成对应的底层方法。
JNIEXPORT jstring JNICALL
Java_cbt_edu_iot_ndksample_MainActivity_stringFromJNI2(JNIEnv *env, jobject instance) {
// TODO
return env->NewStringUTF(returnValue);
}
参考之前的方法将错误修复。
extern "C"
JNIEXPORT jstring JNICALL
Java_cbt_edu_iot_ndksample_MainActivity_stringFromJNI2(JNIEnv *env, jobject instance) {
std::string hello = "Hello from C++ 2";
return env->NewStringUTF(hello.c_str());
}
修改MainActivity
代码,调用新添加的native方法stringFromJNI2()
。
// tv.setText(stringFromJNI());
tv.setText(stringFromJNI2());
构建和运行示例应用
点击 Run 后,Android Studio 将在您的 Android 设备或者模拟器上构建并启动一个显示文字“Hello from C++ 2”的应用。下面的概览介绍了构建和运行示例应用时会发生的事件:
- Gradle 调用您的外部构建脚本
CMakeLists.txt
。 - CMake 按照构建脚本中的命令将 C++ 源文件
native-lib.cpp
编译到共享的对象库中,并命名为libnative-lib.so
,Gradle 随后会将其封装到 APK 中。 - 运行时,应用的
MainActivity
会使用System.loadLibrary()
) 加载原生库。现在,应用可以使用库的原生函数stringFromJNI()
。 MainActivity.onCreate()
调用stringFromJNI()
,这将返回“Hello from C++”并使用这些文字更新TextView
。
注:Instant Run 与使用原生代码的项目不兼容。Android Studio 会自动停用此功能。
如果您想要验证 Gradle 是否已将原生库封装到 APK 中,可以使用 APK 分析器:
- 选择 Build > Analyze APK。
- 从
app/build/outputs/apk/
目录中选择 APK 并点击 OK。 如图 3 中所示,您会在 APK 分析器窗口的
lib/<ABI>/
下看到libnative-lib.so
。图 3.使用 APK 分析器定位原生库。
提示:如果您想要试验使用原生代码的其他 Android 应用,请点击 File > New > Import Sample 并从 Ndk 列表中选择示例项目。
向现有项目添加 C/C++ 代码
如果您希望向现有项目添加原生代码,请执行以下步骤:
创建新的原生源文件并将其添加到您的 Android Studio 项目中。
- 如果您已经拥有原生代码或想要导入预构建的原生库,则可以跳过此步骤。
创建 CMake 构建脚本,将您的原生源代码构建到库中。如果导入和关联预构建库或平台库,您也需要此构建脚本。
- 如果您的现有原生库已经拥有
CMakeLists.txt
构建脚本或者使用 ndk-build 并包含Android.mk
构建脚本,则可以跳过此步骤。
- 如果您的现有原生库已经拥有
提供一个指向您的 CMake 或 ndk-build 脚本文件的路径,将 Gradle 关联到您的原生库。Gradle 使用构建脚本将源代码导入您的 Android Studio 项目并将原生库(SO 文件)封装到 APK 中。
配置完项目后,您可以使用 JNI 框架从 Java 代码中访问您的原生函数。要构建和运行应用,只需点击 Run 。Gradle 会以依赖项的形式添加您的外部原生构建流程,用于编译、构建原生库并将其随 APK 一起封装。
创建新的原生源文件
要在应用模块的主源代码集中创建一个包含新建原生源文件的 cpp/
目录,请按以下步骤操作:
- 从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
- 导航到您的模块 > src,右键点击 main 目录,然后选择 New > Directory。
- 为目录输入一个名称(例如
cpp
)并点击 OK。 - 右键点击您刚刚创建的目录,然后选择 New > C/C++ Source File。
- 为您的源文件输入一个名称,例如
native-lib
。 从 Type 下拉菜单中,为您的源文件选择文件扩展名,例如
.cpp
。- 点击 Edit File Types
,您可以向下拉菜单中添加其他文件类型,例如
.cxx
或.hxx
。在弹出的 C/C++ 对话框中,从 Source Extension 和 Header Extension 下拉菜单中选择另一个文件扩展名,然后点击 OK。
- 点击 Edit File Types
,您可以向下拉菜单中添加其他文件类型,例如
如果您还希望创建一个标头文件,请选中 Create an associated header 复选框。
- 点击 OK。
创建 CMake 构建脚本
如果您的原生源文件还没有 CMake
构建脚本,则您需要自行创建一个并包含适当的 CMake 命令。CMake
构建脚本是一个纯文本文件,您必须将其命名为
CMakeLists.txt
。本部分介绍了您应包含到构建脚本中的一些基本命令,用于在创建原生库时指示
CMake 应使用哪些源文件。
注:如果您的项目使用 ndk-build,则不需要创建 CMake
构建脚本。提供一个指向您的
Android.mk
文件的路径,将 Gradle 关联到您的原生库。
要创建一个可以用作 CMake 构建脚本的纯文本文件,请按以下步骤操作:
- 从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
右键点击您的模块的根目录并选择 New > File。
注:您可以在所需的任意位置创建构建脚本。不过,在配置构建脚本时,原生源文件和库的路径将与构建脚本的位置相关。
输入“CMakeLists.txt”作为文件名并点击 OK。
现在,您可以添加 CMake 命令,对您的构建脚本进行配置。要指示 CMake
从原生源代码创建一个原生库,请将
cmake_minimum_required()
和
add_library()
命令添加到您的构建脚本中:
# 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 构建脚本添加源文件或库时,Android
Studio 还会在您同步项目后在 Project
视图下显示关联的标头文件。不过,为了确保 CMake
可以在编译时定位您的标头文件,您需要将
include_directories()
命令添加到 CMake 构建脚本中并指定标头的路径:
add_library(...)
# Specifies a path to native header files.
include_directories(src/main/cpp/include/)
CMake 使用以下规范来为库文件命名:
lib库名称.so
例如,如果您在构建脚本中指定“native-lib”作为共享库的名称,CMake
将创建一个名称为 libnative-lib.so
的文件。不过,在 Java
代码中加载此库时,请使用您在 CMake 构建脚本中指定的名称:
static {
System.loadLibrary(“native-lib”);
}
注:如果您在 CMake 构建脚本中重命名或移除某个库,您需要先清理项目,Gradle 随后才会应用更改或者从 APK 中移除旧版本的库。要清理项目,请从菜单栏中选择 Build > Clean Project。
Android Studio 会自动将源文件和标头添加到 Project 窗格的 cpp
组中。使用多个 add_library()
命令,您可以为 CMake
定义要从其他源文件构建的更多库。
添加 NDK API
Android NDK 提供了一套实用的原生 API 和库。通过将 NDK
库包含到项目的
CMakeLists.txt
脚本文件中,您可以使用这些 API 中的任意一种。
预构建的 NDK 库已经存在于 Android 平台上,因此,您无需再构建或将其封装到 APK 中。由于 NDK 库已经是 CMake 搜索路径的一部分,您甚至不需要在您的本地 NDK 安装中指定库的位置 - 只需要向 CMake 提供您希望使用的库的名称,并将其关联到您自己的原生库。
将
find_library()
命令添加到您的 CMake 构建脚本中以定位 NDK
库,并将其路径存储为一个变量。您可以使用此变量在构建脚本的其他部分引用
NDK 库。以下示例可以定位 Android
特定的日志支持库并将其路径存储在
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 )
为了确保您的原生库可以在 log
库中调用函数,您需要使用 CMake
构建脚本中的
target_link_libraries()
命令关联库:
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
还以源代码的形式包含一些库,您在构建和关联到您的原生库时需要使用这些代码。您可以使用
CMake 构建脚本中的 add_library()
命令,将源代码编译到原生库中。要提供本地 NDK 库的路径,您可以使用
ANDROID_NDK
路径变量,Android Studio 会自动为您定义此变量。
以下命令可以指示 CMake 构建 android_native_app_glue.c
,后者会将
NativeActivity
生命周期事件和触摸输入置于静态库中并将静态库关联到 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} )
添加其他预构建库
添加预构建库与为 CMake
指定要构建的另一个原生库类似。不过,由于库已经预先构建,您需要使用
IMPORTED
标志告知 CMake 您只希望将库导入到项目中:
add_library( imported-lib
SHARED
IMPORTED )
然后,您需要使用
set_target_properties()
命令指定库的路径,如下所示。
某些库为特定的 CPU 架构(或应用二进制接口
(ABI))提供了单独的软件包,并将其组织到单独的目录中。此方法既有助于库充分利用特定的
CPU 架构,又能让您仅使用所需的库版本。要向 CMake 构建脚本中添加库的多个
ABI 版本,而不必为库的每个版本编写多个命令,您可以使用 ANDROID_ABI
路径变量。此变量使用 NDK 支持的一组默认
ABI,或者您手动配置
Gradle 而让其使用的一组经过筛选的 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 可以在编译时定位您的标头文件,您需要使用
include_directories()
命令,并包含标头文件的路径:
include_directories( imported-lib/include/ )
注:如果您希望封装一个并不是构建时依赖项的预构建库(例如在添加属于
imported-lib
依赖项的预构建库时),则不需要执行以下说明来关联库。
要将预构建库关联到您自己的原生库,请将其添加到 CMake 构建脚本的
target_link_libraries()
命令中:
target_link_libraries( native-lib imported-lib app-glue ${log-lib} )
在您构建应用时,Gradle 会自动将导入的库封装到 APK 中。您可以使用 APK 分析器验证 Gradle 将哪些库封装到您的 APK 中。如需了解有关 CMake 命令的详细信息,请参阅 CMake 文档。
将 Gradle 关联到您的原生库
要将 Gradle 关联到您的原生库,您需要提供一个指向 CMake 或 ndk-build 脚本文件的路径。在您构建应用时,Gradle 会以依赖项的形式运行 CMake 或 ndk-build,并将共享的库封装到您的 APK 中。Gradle 还使用构建脚本来了解要将哪些文件添加到您的 Android Studio 项目中,以便您可以从 Project 窗口访问这些文件。如果您的原生源文件没有构建脚本,则需要先创建 CMake 构建脚本,然后再继续。
将 Gradle 关联到原生项目后,Android Studio 会更新 Project 窗格以在 cpp 组中显示您的源文件和原生库,在 External Build Files 组中显示您的外部构建脚本。
注:更改 Gradle 配置时,请确保通过点击工具栏中的 Sync Project 应用更改。此外,如果在将 CMake 或 ndk-build 脚本文件关联到 Gradle 后再对其进行更改,您应当从菜单栏中选择 Build > Refresh Linked C++ Projects,将 Android Studio 与您的更改同步。
使用 Android Studio UI
您可以使用 Android Studio UI 将 Gradle 关联到外部 CMake 或 ndk-build 项目:
- 从 IDE 左侧打开 Project 窗格并选择 Android 视图。
- 右键点击您想要关联到原生库的模块(例如 app 模块),并从菜单中选择 Link C++ Project with Gradle。您应看到一个如图 4 所示的对话框。
从下拉菜单中,选择 CMake 或 ndk-build。
- 如果您选择 CMake,请使用 Project Path 旁的字段为您的外部
CMake 项目指定
CMakeLists.txt
脚本文件。 如果您选择 ndk-build,请使用 Project Path 旁的字段为您的外部 ndk-build 项目指定
Android.mk
脚本文件。如果Application.mk
文件与您的Android.mk
文件位于相同目录下,Android Studio 也会包含此文件。图 4.使用 Android Studio 对话框关联外部 C++ 项目。
- 如果您选择 CMake,请使用 Project Path 旁的字段为您的外部
CMake 项目指定
点击 OK。
手动配置 Gradle
要手动配置 Gradle 以关联到您的原生库,您需要将 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"
}
}
}
注:如果您想要将 Gradle 关联到现有 ndk-build 项目,请使用
ndkBuild {}
块而不是 cmake {}
,并提供
Android.mk
文件的相对路径。如果
Application.mk
文件与您的
Android.mk
文件位于相同目录下,Gradle 也会包含此文件。
指定可选配置
您可以在模块级 build.gradle
文件的 defaultConfig {}
块中配置另一个
externalNativeBuild {}
块,为 CMake 或 ndk-build
指定可选参数和标志。与 defaultConfig {}
块中的其他属性类似,您也可以在构建配置中为每个产品风味重写这些属性。
例如,如果您的 CMake 或 ndk-build 项目定义多个原生库,您可以使用
targets
属性仅为给定产品风味构建和封装这些库中的一部分。以下代码示例说明了您可以配置的部分属性:
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 {...}
}
}
要详细了解配置产品风味和构建变体,请参阅配置构建变体。如需了解您可以使用
arguments
属性为 CMake 配置的变量列表,请参阅使用 CMake
变量。
指定 ABI
默认情况下,Gradle 会针对 NDK 支持的
ABI
将您的原生库构建到单独的 .so
文件中,并将其全部封装到您的 APK
中。如果您希望 Gradle 仅构建和封装原生库的特定 ABI 配置,您可以在模块级
build.gradle
文件中使用 ndk.abiFilters
标志指定这些配置,如下所示:
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 {...}
}
在大多数情况下,您只需要在 ndk {}
块中指定
abiFilters
(如上所示),因为它会指示 Gradle
构建和封装原生库的这些版本。不过,如果您希望控制 Gradle
应当构建的配置,并独立于您希望其封装到 APK 中的配置,请在
defaultConfig.externalNativeBuild.cmake {}
块(或
defaultConfig.externalNativeBuild.ndkBuild {}
块中)配置另一个
abiFilters
标志。Gradle 会构建这些 ABI 配置,不过仅会封装您在
defaultConfig.ndk{}
块中指定的配置。
为了进一步降低 APK 的大小,请考虑配置 ABI APK
拆分,而不是创建一个包含原生库所有版本的大型
APK,Gradle 会为您想要支持的每个 ABI 创建单独的 APK,并且仅封装每个 ABI
需要的文件。如果您配置 ABI 拆分,但没有像上面的代码示例一样指定
abiFilters
标志,Gradle 会构建原生库的所有受支持 ABI
版本,不过仅会封装您在 ABI
拆分配置中指定的版本。为了避免构建您不想要的原生库版本,请为
abiFilters
标志和 ABI 拆分配置提供相同的 ABI 列表。