Android NDK使用指南(基础篇)

引言

在 Android 开发中,大多数应用程序都是用 Java 或 Kotlin 编写的。然而,有时候我们需要使用 C 或 C++ 代码来提高性能,或者为了与现有的 C/C++ 库集成。Android NDK就是为此目的而设计的工具包。本文将介绍Android NDK的相关基本概念和基础使用方法,帮助读者初步理解NDK。有关NDK的原理及更高级的使用技巧将在后续的进阶篇中进行介绍(咕咕咕)。

什么是 Android NDK?

Android NDK 是一个工具集,允许开发者在 Android 应用中使用 C 和 C++ 代码。通过 NDK,可以:

  • 实现高性能的计算任务,如游戏引擎、图像处理等。
  • 重用现有的 C/C++ 库,提高开发效率。
  • 在某些情况下,通过优化和使用更底层的语言来提升应用性能。

NDK 基础概念

NDK (Native Development Kit)

NDK 是 Android 提供的一套工具集,允许在 Android 应用中使用本地代码(C/C++)。NDK 提供了与系统 API 交互的功能,使开发者能够编写更高效的代码、访问底层硬件、以及使用现有的 C/C++ 库。

JNI(Java Native Interface)

JNI 是 Java 平台的一部分,用于实现 Java 代码与本地(Native)代码之间的互操作。通过 JNI,Java 方法可以调用 C/C++ 函数,反之亦然。JNI 是 NDK 编程的核心,理解 JNI 是掌握 NDK 编程的关键。

JNI 编程详解

1. 基本数据类型映射

Java类型 Native类型 符号
boolean jboolean Z
byte jbyte B
char jchar C
short jshort S
int jint I
long jlong J
float jfloat F
double jdouble D
void void V
String jstring Ljava/lang/String;
Object jobject L+包名/类名+$嵌套类+;
数组 数组+Array [基本类型符号

注:若Java类型为数组,则对应Native类型为基本类型+Array,打个比方说明,

Java类型为byte\[\],则Native类型为jbyteArray,符号为[B

2. JNI 函数定义与实现

下面以两个demo简单说明Java调用C++和C++调用Java的基本步骤:

  • Java调用C/C++代码流程
java 复制代码
// Java层定义
public class NativeLib {
    static {
        System.loadLibrary("native-lib");
    }
    public native String stringFromJNI();
}
c 复制代码
// 对应的C/C++实现
#include <jni.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapp_NativeLib_stringFromJNI(JNIEnv* env, jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
  • C/C++调用Java代码流程
java 复制代码
// Java层实现
public class NativeLib {
    public String getMessageFromJava() {
        return "Hello from Java";
    }
}
c 复制代码
// C/C++层定义
#include <jni.h>
JavaVM* g_javaVM = nullptr;​
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
    if (jvm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    // Java 虚拟机实例的全局引用
    g_javaVM = jvm;
    return JNI_VERSION_1_6;
}
​
std::string callJavaMethod() {
    JNIEnv* env = nullptr;
    // 将本地线程附加到Java虚拟机
    g_javaVM->AttachCurrentThread(&env, nullptr);
    // 查找 Java 类
    jclass clazz = env->FindClass("com/example/myapp/NativeLib");
    // 查找构造方法 ID
    jmethodID constructor = env->GetMethodID(clazz, "<init>", "()V");
    // 创建 Java 类的实例
    jobject instance = env->NewObject(clazz, constructor);
    // 查找实例方法 ID
    jmethodID methodID = env->GetMethodID(clazz, "getMessageFromJava", "()Ljava/lang/String;");
    // 调用实例方法
    std::string message = env->CallObjectMethod(instance, methodID);
    // 将本地线程与 Java 虚拟机分离
    g_javaVM->DetachCurrentThread();
    return message;
}
相关推荐
Lazionr1 小时前
模板进阶:深入理解模板机制
c++·windows
豆沙沙包?8 小时前
C++~~~stack容器、queue容器、list容器(p45-P56)
c++·windows·list
Frank_refuel8 小时前
【C++八股】面向对象
开发语言·c++
h_a_o777oah8 小时前
【图论】Tarjan 缩点:解决有向图中环的问题
c++·算法·图论·acm·强连通分量·缩点·tarjan
weixin_403810138 小时前
AI智能体写安卓自动化脚本教程:Cursor/Trae+CLI 实战,自然语言生成代码
android·人工智能·自动化·跨境电商·安卓自动化脚本·多账户运营
别动我齐刘海10 小时前
机器人运动控制学习4——状态估计 State Estimation
c++·人工智能·学习·目标检测·机器学习·机器人·自动驾驶
呆呆小孩10 小时前
零基础学 MySQL(上):从建库建表到增删改查,一篇搭好 SQL 基础
android·sql·mysql
学习星球10 小时前
OpenHarness 全面配置教学——从游戏开发工作流引入
c++·游戏·ai·ai编程
catchadmin11 小时前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
android·ios·ai·php
wWYy.11 小时前
C++与C的区别
c语言·c++