1.ndk(Native Development Kit) 概念
NDK包括了:
- 从C / C++生成原生代码库所需要的工具和build files。
- 将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files ,即.apk文件)中。
- 支持所有未来Android平台的一系列原生系统头文件和库
为何要用到NDK?
- 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库被反编译的难度较大。
- 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
- 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。
2.android studio项目中c++代码添加和调试
-
下载必要组件
- Android 原生开发工具包 (NDK):这套工具集允许您为 Android 使用 C 和 C++ 代码,并提供众多平台库,让您可以管理原生 Activity 和访问物理设备组件,例如传感器和触摸输入。
- CMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。
- LLDB:一种调试程序,Android Studio 使用它来调试c++代码,可以在调试断点处查看/更改变量值、执行函数等等。
可以通过sdk manager来下载这些组件。
-
创建支持c++的项目
创建项目时勾选include c++ support
然后next到Customize C++ Support配置c++选项
c++选项释义如下:
- 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。
配置和组建项目
创建项目完成后会默认在app moudle根目录下创建CMakeList.txt,c++代码默认放在src-main-cpp目录下。可以在app的build-gradle中指定cmake的执行文件路径、过滤生成的abi种类等。可以通过CMakeList.txt定义原生库文件的依赖、输出so文件路径/名称等。值得注意的是有一些变量在cmake官方库中未定义,这些变量是在android.toolchain.cmake中的,例如ANDROID_ABI变量。studio 的Instant Run与使用原生代码的项目不兼容。Android Studio 会自动停用原生项目的此功能。
- 指定ABI:
默认情况下,Gradle 会针对 NDK 支持的 ABI将您的原生库构建到单独的 .so
文件中,并将其全部打包到您的 APK 中。如果您希望 Gradle 仅构建和打包原生库的特定 ABI 配置,您可以在模块级 build.gradle
文件中使用 ndk.abiFilters
标志指定这些配置,如下所示:
android {
...
defaultConfig {
...
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 {}
块配置另一个 abiFilters
标志。
实际测试两者效果并没有什么差别,都会控制库文件输出以及apk的.so文件架构平台。tips:使用 Build > Analyze APK可以查看apk包含的原生.so文件。
- cmake更改输出库目录:
cmake文件不展开说明了,此处为更改输出so路径为项目根目录的libss目录下:
其中设置CMAKE_LIBRARY_OUTPUT_DIRECTORY方式需要在add_library之前设置,set_target_properties方式需要在add_library之后设置,设置LIBRARY_OUTPUT_PATH的方式实际测验无效。
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../libss/${ANDROID_ABI})
# Old library location variable。老版本的变量,cmake官网虽然没有说明,实际测试已经无法工作了
#set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../libss/${ANDROID_ABI})
add_library( # Sets 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 )
#自定义target目录,可以设置特定名字target的属性,也可以直接更改默认的所有target的输出路径,文件夹不存在会自动创建。
#set_target_properties(native-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../libss/${ANDROID_ABI} )
- 运行构建:
执行build—>make moudle app
小结:
android studio2.2起开始c++代码可以直接在studio中编写打包入apk了,studio默认使用cmake进行构建原生库,cmake所做的其实是生成MakeFiles然后再调用ndk-build生成.so文件。cmake可以指定toolchain来生成android平台的库,如果不指定默认生成对应平台的库,windows下是.dll文件,mac下是.dylib文件,studio中默认使用的是sdk下的cmake下的android.toolchain.cmake工具链文件来生成so文件。本地的android.toolchain.cmake文件路径可以在app-.externalNativeBuild-debug-cmake_build_command.txt中查看,默认路径是:/Users/mac02/Library/Android/sdk/cmake/3.6.4111459/android.toolchain.cmake