十年前写过一篇介绍NDK开发的文章《Android实战技巧之二十三:Android Studio的NDK开发》,今天看来已经发生了很多变化,NDK开发变得更加容易了。下面就写一篇当下NDK开发快速入门。
**原生开发套件 (NDK) **是一套工具,使开发者能够在 Android 应用中使用 C 和 C++ 代码,并提供众多平台库。官方默认使用CMake作为构建工具。
一、NDK 核心作用
- 高性能计算:图像处理、物理仿真、音视频编解码
- 复用现有库:OpenCV、FFmpeg、TensorFlow Lite
- 底层硬件访问:传感器、GPU 指令集(如 NEON/VFP)
- 安全敏感操作:加密算法、反调试逻辑
二、环境配置
1.工具链安装
- Android Studio:SDK Manager → NDK (Side by side)
- CMake:外部构建工具,可与 Gradle 搭配使用来构建原生库。
- LLDB:Native 代码调试器(如果仅仅尝试NDK,可以暂且不用它)
三、实践开始:打通kotlin和Cpp端
新建项目自不必说。
新建kotlin文件
比如新建一个nativelib包,下面新建一个NativeTest.kt。编写两个方法如下:
package com.example.kotlinlearningproject.nativelib
class NativeTest {
external fun add(one: Int, two: Int): Int
// external fun addString(one: String): String
companion object {
init {
System.loadLibrary("native-lib")
}
}
}
新建cpp文件
在src->main下新建cpp目录,并新建一个cpp文件叫native-lib.cpp。
对应按规则直接写Cpp对应的方法,如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <string.h>
/* Header for class com_example_kotlinlearningproject_nativelib_NativeTest */
#ifndef _Included_com_example_kotlinlearningproject_nativelib_NativeTest
#define _Included_com_example_kotlinlearningproject_nativelib_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_com_example_kotlinlearningproject_nativelib_NativeTest_add
(JNIEnv *env, jobject obj, jint one, jint two){
return one + two;
}
#ifdef __cplusplus
}
#endif
#endif
当然了,你可以用javah工具或者java -h 命令生成头文件,更安全。如果觉得自己不会犯低级错误,直接就着上面改,也没啥问题。
新建CMakeLists.txt
在app根目录下,新建CMake配置文件。内容如下:
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
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
)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
${log-lib} )
Gradle 配置
app下的build.gradle新增如下内容:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_ARM_NEON=TRUE"
cppFlags "-std=c++17 -frtti -fexceptions"
}
}
ndk {
abiFilters "arm64-v8a"
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
对应的,如果你是build.gradle.kt,那参考下面:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments += "-DANDROID_ARM_NEON=TRUE"
cppFlags += listOf("-std=c++17", "-frtti", "-fexceptions")
}
}
ndk {
abiFilters += listOf("arm64-v8a")
}
}
externalNativeBuild {
cmake {
path = file("CMakeLists.txt")
}
}
}
四、实践开始:新建activity调用上述接口
在Activity中新建一个按钮,btnNdk,点击调用上述接口:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnNdk.setOnClickListener { testNdk() }
}
private fun testNdk() {
val test = NativeTest()
val result = test.add(23,90)
Toast.makeText(this, "调用NDK计算:${result}", Toast.LENGTH_SHORT).show()
}
一切准备就绪了是吧,接下来只需要绿色的run按钮,剩下的都交给Android Studio吧!!!
现在真是做到了无缝衔接java/kotlin与C/C++,确实比十年前进步了一些。