Java Native Interface (JNI) 是 Java 平台的一部分,它允许 Java 代码与用其他编程语言(如 C、C++)编写的本地应用程序或库进行互操作。JNI 提供了一种机制,通过这机制,Java 程序可以调用本地代码,而本地代码也可以调用 Java 代码。
基本概念
- JNI 的用途:
- 调用现有的本地库:重用已经用 C 或 C++ 编写的高效代码库。
- 提高性能:对一些性能要求极高的操作,可以使用 C 或 C++ 实现。
- 访问特定平台特性:使用 Java 不能直接访问的平台特定功能和硬件。
- JNI 环境:
- Java 虚拟机 (JVM):JNI 运行在 JVM 上,通过 JVM 提供的接口与本地代码进行交互。
- 本地方法库:包含用本地语言编写的代码,通常是动态链接库(如 Windows 上的 DLL 或 Unix 上的 SO 文件)。
- 基本结构:
- Java 声明本地方法:在 Java 类中声明一个本地方法,通过
native
关键字。 - 加载本地库:使用
System.loadLibrary()
方法加载包含本地方法实现的库。 - 本地方法实现:在 C/C++ 中实现与 Java 声明匹配的方法,并使用 JNI 提供的接口进行数据交换。
- Java 声明本地方法:在 Java 类中声明一个本地方法,通过
使用Android使用 JNI 详细步骤
1.使用Android Studio新建项目
较新的Android Studio 与旧版的Android Studio 新建方式略有不同,新版创建需要选择**Native C++**项目
选择完毕之后点击Next,给项目起名字,选择开发语言,可选Java和Kotlin
最后点击next 选择C++ Standard
选择C++11 点击Finish 等待加载Gradle配置完项目,第一个JNI程序就搭建好了
2.项目结构分析
与普通的Android项目多了CPP目录,该目录存放C++代码和CMakeLists.txt 指定生成的库和如何加载外部库
在这个CMakeLists.txt中默认指定的信息如下:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.22.1)
# Declares and names the project.
project("firstjni")
# 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.
firstjni
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
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.
firstjni
# Links the target library to the log library
# included in the NDK.
${log-lib})
这个 CMakeLists.txt
文件的主要功能是:
- 设置 CMake 的最低版本:确保使用的 CMake 版本至少是 3.22.1。
- 声明项目:将项目命名为
firstjni
。 - 添加库:定义一个名为
firstjni
的共享库,并指定其源文件为native-lib.cpp
。 - 查找外部库:使用
find_library
查找并设置 Android NDK 提供的log
库。 - 链接库:将
log
库链接到firstjni
库,使其可以使用日志功能。
3.JNI函数接口和C++实现解析
在新建好的MainActivity中会发现,默认生成了一些代码
首先是默认加载C++库,也就是对应cpp的文件夹
// 加载C++库
static {
System.loadLibrary("firstjni");
}
默认生成了 一个JNI函数接口 使用native修饰
Android Studio 左边自动提示生成了C++图标,单击图标就可以跳转到对应的C++实现
extern "C" JNIEXPORT jstring JNICALL
Java_com_marxist_firstjni_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
这个函数是一个典型的 JNI (Java Native Interface) 函数,它定义了一个从 C++ 返回字符串给 Java 的本地方法
函数声明:
extern "C" JNIEXPORT jstring JNICALL
Java_com_marxist_firstjni_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */)
extern "C"
:
- 这个修饰符告诉编译器使用 C 语言的函数命名规则,以防止 C++ 的名称修饰(name mangling)。这样,Java 虚拟机 (JVM) 可以正确地找到这个函数。
JNIEXPORT
:
- 这是一个宏,用于定义 JNI 函数的导出规范,确保函数可以被 JVM 调用。
jstring
:
- 这是函数的返回类型,表示一个 Java 字符串对象。
JNICALL
:
- 这是一个宏,用于定义 JNI 函数的调用规范,确保函数可以按照 JNI 的约定被调用。
Java_com_marxist_firstjni_MainActivity_stringFromJNI
:
- 这是函数的名称。按照 JNI 的命名规则,这个名称由以下部分组成:
Java_
:前缀,表示这是一个 JNI 函数。com_marxist_firstjni_MainActivity
:类的全限定名,其中包名中的点号(.)被替换为下划线(_)。stringFromJNI
:方法名,对应 Java 类中的本地方法名。
JNIEnv* env
:
- 这是一个指向 JNI 环境的指针,提供了调用 JNI 函数的接口。
- JNI (Java Native Interface) 函数的一个重要参数,它是一个指向
JNIEnv
结构体的指针。这个结构体包含了大量的函数指针,这些函数提供了与 JVM 交互的各种功能。通过这个参数,C/C++ 代码可以调用 Java 方法、操作 Java 对象、处理异常等。
jobject
:
- 这是调用该本地方法的 Java 对象实例的引用,表示
this
对象。
4.效果展示
在调用本地方法的Java对象,可以直接调用JNI接口,如下所示:
TextView tv = binding.sampleText;
tv.setText(stringFromJNI());
编译运行之后,第一个JNI程序显示Hello信息
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » JNI概念详解,Android下开发第一个JNI程序
发表评论 取消回复