type
status
date
slug
summary
tags
category
icon
password
一、JNI
作用:用于java代码和C++、c代码的交互(代码混编)。
分类使用:Jni静态注册、jni动态注册
二、静态注册
1、定义被native修饰的方法
public native String Getstring();
2、根据java代码生成.h头文件(javah -jni 类的包名路径)
javah -jni com.example.jnitest.MainActivity
3、编写C/C++代码,导入.h头文件,实现我们.h头文件中方法
#include <JNItest.h> JNIEXPORT jstring JNICALL Java_com_example_jnitest_MainActivity_Getstring (JNIEnv *env, jobject obj) { jstring str = (*env)->NewStringUTF(env, "hello ndk"); return str; }
4、编写(配置)两个mk文件:application.mk/android.mk
#application.mk APP_ABI := armeabi #android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := JNItest LOCAL_SRC_FILES := JNItest.c LOCAL_ARM_MODE := arm LOCAL_LDLIBS += -llog include $(BUILD_SHARED_LIBRARY)
5、通过ndk-build生成so文件
ndk-build
6、java代码中加载so文件/libs文件下去头去尾(头:lib;尾:.so)
static{ System.loadLibrary("JNItest"); }
7、build.gradle文件配置
androi -ddefaultConfig --ndk { // 设置支持的SO库架构 abiFilters 'armeabi' ,'x86', 'armeabi-v7a', 'x86_64','arm64-v8a' }
8、main创建jniLibs文件夹将so文件复制
main -jniLibs --armeabi ---libJNItest.so --armeabi-v7a ---libJNItest.so
三、动态注册
1、.c文件编写JNI_OnLoad
FindClass处填写对应类
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv* env; if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4)!=JNI_OK){ return JNI_ERR; } jclass cls=(*env)->FindClass(env, "com/example/myjnireistest/MainActivity"); if((*env)->RegisterNatives(env, cls, jninativemethod,2)!=JNI_OK){ return JNI_ERR; } return JNI_VERSION_1_4; }
2、.c文件定义方法结构体
JNINativeMethod jninativemethod[]={ { "getInt", "()I", (void*)GetInt }, { "getChar", "()C", (void*)GetChar, } };
3、.c文件对应C函数
jint GetInt (JNIEnv *env, jobject obj){ return 99; } jchar GetChar(JNIEnv* env, jobject obj){ return 'y'; }
4、java代码逻辑
static { System.loadLibrary("MyJniTest"); } public native int getInt(); public native char getChar();
四、SO库获取java层字段值
//反射获取对应类 jclass clazz=(*env)->FindClass(env, "com/example/myjnilogin/MainActivity"); //获取实例字段id (env, clazz, 字段名,字段类型) jfieldID fieldid = (*env)->GetFieldID(env, clazz, "userId","Ljava/lang/String;"); //根据实例id获取对应的值 jstring jstr_user = (*env)->GetObjectField(env, obj, fieldid); //将string转化char const char* user= (*env)->GetStringUTFChars(env, jstr_user, 0);
五、SO库调用JAVA函数
//反射获取方法id jmethodID methodID = (*env)->GetMethodID(env,clazz, "pwError", "()V"); //call调用方法 (*env)->CallVoidMethod(env,obj, methodID);
- 作者:404False
- 链接:https://404nofoundx.top/article/5e0641c5-ba62-4f79-bca1-a6057c1e8fa1
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。