1.什么是JNI
JNI(Java Native Interface)是一种允许Java代码与本地代码(如C或C++)进行交互的技术。它提供了一种机制,使得Java应用程序可以调用本地方法或库,并允许本地代码访问Java应用程序中的对象和方法。
2.配置JNI开发环境NDK
打开Android Studio,点击“Tools”,转到“SDK Manager”,选择“SDK Tools”选项卡,并选中“NDK”和“CMake”进行安装。
3.创建NativeC++类型的项目
你可以创建一个 Android 的 Native C++ 项目,并在其中编写 C++ 代码,并使用 JNI 接口与 Java 代码进行交互。这样你就可以充分利用 C++ 的性能优势,并与 Android 平台进行无缝集成。
其中在 src/main/cpp
目录下
CMakeLists.txt
文件:该文件是用于配置和管理你的 C++ 代码构建过程的主要文件。
native-lib.cpp
文件:你可以在native-lib.cpp
文件里面来实现你的 C++ 代码逻辑。
MainActivity:
中调用 native-lib.cpp
中实现的本地方法
4. 了解CMakeLists.txt
文件
CMakeLists.txt 文件是一个文本文件,用于配置和管理 CMake 构建系统的行为。
#cmake最低版本要求 cmake_minimum_required(VERSION 3.22.1) project("jni_test") # 配置so库编译信息 add_library( # 输出so库的名称 jni_test # 设置生成库的方式,默认为SHARE动态库 SHARED # 列出参与编译的所有源文件 native-lib.cpp) # 查找代码中使用到的系统库 find_library( log-lib log) # 指定编译目标库时,cmake要链接的库 target_link_libraries( # 指定目标库,native-lib 是在上面 add_library 中配置的目标库 jni_test # 列出所有需要链接的库 ${log-lib})
常用的命令有:
1.指定 CMake 的最低版本要求。
#cmake最低版本要求 cmake_minimum_required(VERSION 3.22.1)
2.使用 project
命令来指定项目的名称和版本。
project("jni_test")
3. 通过 set 方法定义了 so 和 头文件 所在目录。
其中 CMAKE_SOURCE_DIR 为系统变量,指向 CMakeLists.txt 所在目录。
set(OPENCV_LIBS_DIR ${CMAKE_SOURCE_DIR}/../opencv_include)
4.引入其他模块。
include_directories(${OPENCV_LIBS_DIR})
5.添加源文件。
#opencv add_library(libopencv_java3 SHARED IMPORTED )
6.set_target_properties
命令可以指定构建结果的输出路径、名称等。
其中ANDROID_ABI 是系统变量,指 向 so 对应的 CPU 框架目录:armeabi、armeabi-v7a、x86 ...
set_target_properties(libopencv_java3 PROPERTIES IMPORTED_LOCATION ${OPENCV_LIBS}/${ANDROID_ABI}/libopencv_java3.so )
7. target_link_libraries
命令,你可以指定要链接到项目中的静态库或动态库。
target_link_libraries( jni_test libopencv_java3 ${log-lib} )
5.了解native-lib.cpp
文件
native-lib.cpp
文件中的内容可以根据你的需求具体编写,但通常会包含以下部分:
- 包含头文件。
#include <jni.h> #include <string>
- 实现本地方法:在
native-lib.cpp
文件中,你需要实现在 JNI 接口文件中声明过的本地方法。这些方法将从 Java 代码中调用。
extern "C" JNIEXPORT jstring JNICALL Java_com_example_jni_1test_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
- 在上述例子中,我们实现了一个名为stringFromJNI 的本地方法,它返回一个字符串给调用方。
6.在 Android 的 MainActivity
中调用 native-lib.cpp
中实现的本地方法
public class MainActivity extends AppCompatActivity { static { System.loadLibrary("jni_test"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //省略 } public native String stringFromJNI(); }
native-lib.cpp
中的本地方法stringFromJNI ()
在 Java 中以相同的方法名进行调用。