十年前寫過一篇介紹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.nativelibclass NativeTest {external fun add(one: Int, two: Int): Int// external fun addString(one: String): Stringcompanion 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" {
#endifJNIEXPORT 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++,確實比十年前進步了一些。
參考官方文檔