Android NDK 开发教程
什么是 Android NDK
Android NDK 全称 Native Development Kit,是 Android 官方提供的一个工具集,可用于加速使用 C/C++ 语言编写的应用程序的开发和性能优化。
使用 NDK 进行开发的主要优势在于:
- 提高了应用程序的性能:使用原生 C/C++ 代码编写可以实现更快的执行速度,能够处理更多的并发请求。
- 可以更好地利用现有代码库:Android NDK 可以使用现有的 C/C++ 库。
- 避免了 Java 语言的一些限制:Java 语言在某些方面受到了限制,特别是在嵌入式设备上运行时。使用 C/C++ 可以获得更多的灵活性。
安装 Android NDK
- 下载并安装 Android Studio:https://developer.android.com/studio
- 打开 Android Studio,并选择要安装的 Android SDK 版本。
- 在 SDK Manager 中选择“SDK Tools”选项卡,找到 NDK 下载并安装。
使用 Android NDK 开发
1. 配置项目
- 在 Android Studio 中创建一个新的项目。
- 配置 CMakeLists.txt 文件,将其放在项目根目录下。示例内容如下:
cmake_minimum_required(VERSION 3.4.1)
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 )
- 在 app/build.gradle 文件中配置支持 CMake 文件。示例内容如下:
android {
...
externalNativeBuild {
cmake {
path "CMakeLists.txt" //指定 CMakeLists.txt 的路径
}
}
}
2. 编写 C++ 代码
- 在 src/main 下创建一个 cpp 目录,并添加一个名为 native-lib.cpp 的文件。示例代码如下:
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndkdemo_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
- 在 MainActivity.java 文件中添加以下代码:
public class MainActivity extends AppCompatActivity {
// 加载带有 native-lib 的库
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 示例:调用一个返回字符串的 native 方法
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
// 定义 native 方法
public native String stringFromJNI();
}
3. Gradle 构建
- 点击 Android Studio 右侧栏的 Gradle,然后展开 app -> Tasks -> android -> build 中的 build 双击执行。此时会对项目进行 Gradle 构建。
- 在 MainActivity.java 文件中运行 stringFromJNI 方法,可以看到应用程序中显示“Hello from C++”。
示例说明
示例 1:使用 SQLite 数据库
- 编写 SQLite C++ API(头文件 sqlite3.h 和源文件 sqlite3.cpp)。
- 在 CMakeLists.txt 文件中添加以下内容:
add_library(
sqlite3
STATIC
${CMAKE_CURRENT_SOURCE_DIR}/sqlite3.h
${CMAKE_CURRENT_SOURCE_DIR}/sqlite3.cpp
)
- 在 Android.mk 文件中添加以下内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sqlite3
LOCAL_SRC_FILES := sqlite3.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
include $(BUILD_STATIC_LIBRARY)
- 在 app/build.gradle 文件中添加 externalNativeBuild 的配置:
externalNativeBuild {
cmake {
path "CMakeLists.txt"
// 增加以下内容
arguments "-DANDROID_TOOLCHAIN=clang",
"-DANDROID_STL=gnustl_static",
"-DANDROID_PLATFORM=android-21"
}
// 增加以下内容
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
示例 2:使用 OpenCV 将图片转换为灰度图像
- 下载并安装 OpenCV。
- 在 CMakeLists.txt 文件中添加以下内容:
set(opencv_libs libopencv_highgui.a libopencv_core.a libopencv_imgproc.a libopencv_imgcodecs.a)
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp
src/main/cpp/OpenCVUtils.cpp
)
...
target_link_libraries(
native-lib
opencv
log
)
add_library(
opencv
SHARED
IMPORTED
)
set_target_properties(
opencv
PROPERTIES IMPORTED_LOCATION
/path/to/opencv/libs/${ANDROID_ABI}/libopencv_java3.so
)
- 在 native-lib.cpp 文件中添加以下内容:
void toGray(Mat& img, Mat& gray) {
cvtColor(img, gray, CV_BGR2GRAY);
}
- 在 OpenCVUtils.cpp 文件中添加以下内容:
extern "C" JNIEXPORT void JNICALL
Java_com_example_ndkdemo_MainActivity_toGray(JNIEnv *env, jobject instance,
jlong matAddrSrc, jlong matAddrDest) {
// 转换两个 Mat 对象
Mat &src = *(Mat *) matAddrSrc;
Mat &dest = *(Mat *) matAddrDest;
toGray(src, dest);
}
- 在 MainActivity.java 文件中添加以下内容:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
System.loadLibrary("opencv_java3");
}
private Mat srcMat;
private Mat grayMat;
private Bitmap grayBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 示例:将图片转换为灰度图像
ImageView imageView = findViewById(R.id.imageView);
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageView.setImageBitmap(srcBitmap);
srcMat = new Mat();
Utils.bitmapToMat(srcBitmap, srcMat);
grayMat = new Mat();
grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565);
Utils.matToBitmap(grayMat, grayBitmap);
toGray(srcMat.getNativeObjAddr(), grayMat.getNativeObjAddr());
Utils.matToBitmap(grayMat, grayBitmap);
}
public native void toGray(long matAddrSrc, long matAddrDest);
}
结论
此教程详细讲解了 Android NDK 的安装和使用步骤,包含代码示例说明。使用 Android NDK 开发可以提高应用程序的性能,使用现有的 C/C++ 库,也可以获得更多的灵活性。通过深入了解 Android NDK,可以大大提高应用程序的性能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android NDK 开发教程 - Python技术站