Andoid NDK编程 4 - Android Studio for NDK

Google一直在大力推进着Android Studio的开发,之前就已经开始支持native code的开发了(采用gradle-experimental)。但是直到Android Studio 2.2 release后,利用Android Studio开发Native程序才变得好玩起来了。

最新变化

Android Studio 2.2 以及 Android Plugin for Gradle version 2.2.0是目前为止最新的release。二者同时使用,能够让你很轻松地在Android Studio中开发Native代码了,其中的显著变化有:

  1. CMake成为了native代码默认的build tool。Google终于开始放弃传统的ndk-build了(当然,目前这种方式依然还是支持的)。考虑到目前大多数的C/C++项目都采用了CMake,此举无疑为已有native库的移植提供极大的便利。其实以前也可以用CMake为Android做交叉编译, 可以参考我的这篇文章。但是现在更方便了,变成默认就支持了。
  2. Gradle已经支持将native代码build成library并且将其打包到APK中了。
  3. 创建一个Android应用的project的时候,可以在创建向导中直接指定创建native部分了:包括native代码,CMakeLists.txt,以及在build.gradle中将native lib引入到Java部分中去。整个框架会自动为你生成浩,我们只需基于此框架继续开发就好了。

如何开始

首先如果你还没有升级Android Studio的话,赶紧升级到2.2吧。

接下来打开SDK Manager,下载 LLDB, CMake,以及 NDK等:

BTW,LLDB是Android Studio调试native代码的debugger。

接下来用Android Studio中创建一个包含Native代码的项目试试吧,记住在第一步中勾选include C++ support。

项目创建完成后,项目的Android View如下:

其中1是用来放C/C++代码的地方, 2是CMakeLists.txt,用来描述如何build native代码。

此外,还可以看看build.gradle,弄清楚gradle是如何将native集成到project中去的。

已有的native项目

问题来了,如果我们已经有了native的代码,如何通过android studio/gradle应用到android app中呢?

首先如果你的C++项目还没有CMakeList.txt,先把它加上,然后确保能够在你的电脑(Mac/Ubuntu… whatever)上能够build通过。然后将其拷贝到你的项目模块的src/main/cpp下面。

那么有了C++代码以及CMakeList.txt,如何将其link到java部分呢?
如果前面弄明白了build.gradle是如何描述native build的,那么这个问题也就变得很容易了。

我在这贴个例子吧,看看externalNativeBuild出现的两个地方相信你就明了了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion '23.0.2'

defaultConfig {
applicationId 'com.example.nativecodec'
minSdkVersion 21
targetSdkVersion 22
ndk {
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
}
externalNativeBuild {
cmake {
arguments '-DANDROID_PLATFORM=android-21',
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
}
}
}
buildTypes {
release {
minifyEnabled = false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path 'src/main/cpp/CMakeLists.txt'
}
}
}

CMake

如果你对CMake还不是太熟悉,那么抓紧时间学习一下通用的CMakeList.txt是如何书写的,很简单的,对照例子很快就能上手了。具体的用法就不啰嗦了,在这里只是想说一下如何将一个已经build好的library引入进来,也就是说在你的c++代码中如何使用一个已经提前准备好的library。具体来说在native代码的CMakeLists.txt中加入三个部分:

  • 首先声明要使用的库:

假设我们想给这个引入的库起个‘别名’叫做imported-lib

1
2
3
add_library( imported-lib
SHARED
IMPORTED )

  • 然后指明这个库在什么地方:

假设你有一个库libimported-lib.so放在了imported-lib/src/${ANDROID_ABI}/目录下面:

1
2
3
4
5
6
7
8
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 )
  • 最后

在build你自己native代码库的时候,去链接这个prebuilt库:

1
target_link_libraries( native-lib imported-lib ${other-libs} )

Reference

Add C and C++ Code to Your Project