Android NDK使用指南(进阶篇一)

引言

《Android NDK 使用指南(基础篇)》中,我已经介绍了NDK开发的基础知识,还不懂什么是NDK和JNI的小伙伴可以先学习一下基础篇。本文将深入探讨JNI的原理和基本工作流程,帮助读者真正掌握NDK编程。

JNI工作流程

Android中可以通过JNI实现Java和C/C++代码的相互调用,那么它们之间具体是如何交互的呢?下面将为大家进行介绍。

jni流程图.png

上图展示了Java和C/C++是如何通过JNI进行交互的,下面以基础篇中的示例代码为基础,介绍其中的几个关键步骤。

1. 加载Native库(Load JNI Library)

2.png

3.png

当Android的JVM(Java Virtual Machine)执行System.loadLibrary() 函数时, 首先会去执行C组件(.so)里的JNI_OnLoad() 函数。它主要有两个作用:

(1)设置JNI版本
如果你的.so没有提供JNI_OnLoad()函数,VM会默认该.so是使用最老的JNI 1.1版本。由于新版的JNI做了许多扩充,如果需要使用JNI的新版功能,例如JNI 1.4的java.nio.ByteBuffer,就必须借由JNI_OnLoad()函数来告知VM。

(2)设定初始值
由于VM执行到System.loadLibrary()函数时,就会立即先呼叫JNI_OnLoad(),所以C组件的开发者可以借由JNI_OnLoad()来进行C组件内的初期值之设定。

2. JNI环境处理—Java调用C++(Find Native Method)

4.png

extern "C"

表示告诉编译前使用C语言方式编译这段代码,防止对函数名被改变(因为C++允许函数重载)。

JNIEXPORT和JNICALL

JNIEXPORT用于导出函数到JVM中,JNICALL定义了函数调用的约定。

Java_com_example_myapp_NativeLib_stringFromJNI

函数名,固定以**Java_**开头,com_example_myapp对应包名NativeLib对应类名,stringFromJNI对应方法名。

JNIEnv* env

这是一个指向JNI环境的指针,提供了一组操作Java对象和调用Java方法的函数。

jobject

这是一个引用,表示调用这个本地方法的Java对象。

3.JNI环境处理—C++调用Java(Find Java Class)

5.png

g_javaVM->AttachCurrentThread(&env, nullptr)

将当前本地线程附加到Java虚拟机,获取JNI环境。

jclass clazz = env->FindClass("com/example/myapp/NativeLib")

查找Java类com/example/myapp/NativeLib,并返回其对应的jclass对象。

jmethodID constructor = env->GetMethodID(clazz, "<init>", "()V")

获取类的构造方法ID。 “<init>” 是构造方法的特殊名称, “()V” 表示无参数且无返回值的构造方法。

jobject instance = env->NewObject(clazz, constructor)

创建NativeLib类的一个实例对象。

jmethodID methodID = env->GetMethodID(clazz, "getMessageFromJava", "()Ljava/lang/String;")

获取实例方法getMessageFromJava的ID,该方法返回一个Java字符串。

jstring message = (jstring)env->CallObjectMethod(instance, methodID)

调用getMessageFromJava方法并获取返回的Java字符串对象。

g_javaVM->DetachCurrentThread()

将当前本地线程与Java虚拟机分离。

参考资料

  1. NDK官方文档
  2. JNI官方文档
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值