一.什么是JNI?
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。
二.JNI优缺点:
优点:
通过JNI接口,java可以调用C/C++的方法。而C/C++相比java而言,运行的效率得到了大大的提高。
缺点:
一旦使用JNI,JAVA程序就丧失了JAVA平台的两个优点:
1、程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。
2、程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,应该让本地方法集中在少数几个类当中。这样就降低了JAVA和C之间的耦合性。
三.举个栗子
像游戏,视频播放器,图像识别开发都需要用到JNI,纯java是很难做到的。
四.实战
1.环境:
Android Studio 3.5.2
Build #AI-191.8026.42.35.5977832, built on October 31, 2019
JRE: 1.8.0_202-release-1483-b03 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
2. 配置NDK
创建Android工程(我创建的工程的包名为:com.example.so_lib)
local.properties文件中配置:
app build.gradle 文件配置
'''
android {
…………
ndk {//设置支持的SO库架构
abiFilters"armeabi","armeabi-v7a","x86","arm64-v8a","arm64-v8a","x86_64"
moduleName"HezhiJniTest"
ldLibs"EGL","GLESv3","dl","log"
}
sourceSets.main {
jni.srcDirs = []//disable automatic ndk-build call
jniLibs.srcDir"src/main/libs"
}
…………
}
'''
3.创建JNI调用类
4.生成C/C++头文件
编译JNI调用类(用小锤锤锤一下)
到app\build\intermediates\javac\debug\classes 目录下,执行javah -jni com.example.so_lib.HezhiJniTest命令 (javah -jni 包名.HezhiJniTest)
生成了一个.h文件
5.生成so库
创建一个jni目录,将生成的com_example_so_lib_HezhiJniTest.h文件拷贝到jni目录下
在jni目录下,创建com_example_so_lib_HezhiJniTest.h对应的.c文件 ,并实现声明的方法
(我创建的文件为JNI_test.c)
#include "com_example_so_lib_HezhiJniTest.h"
JNIEXPORT jstring JNICALL Java_com_example_so_1lib_HezhiJniTest_getText
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"何止JNI学习");
}
在jni目录下,创建Application.mk文件
# ndk库函数版本号,与SDK版本号一致
APP_PLATFORM :=android-29
# so运行的cpu类型
APP_ABI :=all
APP_STL:=c++_static
在jni目录下,创建Android.mk文件
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=JniTest
LOCAL_SRC_FILES :=JNI_test.c
include $(BUILD_SHARED_LIBRARY)
在命令行进入jni目录 运行ndk-build 生成各种架构的so库
6.so库的使用
将生成的so库拷贝到jniLibs目录下
调用so库里面的方法
7.验证
将打包好的apk部署到模拟器上验证,大功告成。
网友评论