【Android】JNI静态与动态注册介绍
2023-06-13 09:15:16 时间
【Android】JNI静态与动态注册介绍
JNI的两种注册机制:静态注册和动态注册.
JNI介绍
JNI(Java Native Interface),即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互.
方式:
- 静态注册
- 动态注册:需要提供Java中Native方法的方法签名和Native层中对应的实现函数。
静态注册
要求C/C++层的函数名符合某种特定的要求:包含Java中Native方法的目录信息和方法名。
Example
Java
package cn.com.codingce.ndkpractice;
public native String stringFromJNI();
C++
extern "C"
JNIEXPORT jstring JNICALL
Java_cn_com_codingce_ndkpractice_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) {
std::string hello = "Hello from C++";
//crashTest();
return env->NewStringUTF(hello.c_str());
}
按照以上规则进行命名,在调用到Native的方法时,JVM会去查找是否存在对应函数名的函数,以此实现静态注册。
动态注册
动态注册相对于静态注册,优点是不再根据特定路径查找函数的实现,带来两个好处:
- 没有了冗杂的函数名,适用于大型项目开发。
- 由于不再根据Native函数查找对应的JNI层函数,所以首次调用速度比静态注册快。
开发者需要自行提供Java层和C/C++层中的映射关系。
一种可行的方法是基于JNI重载JNI_OnLoad(),在其中对函数进行动态注册。
Example
Java
package cn.com.codingce.ndkpractice.utils;
public static native void logInit(String logFilePath, String logName, int logfileLevel, int logScreenLevel);
C++
此步骤涉及到如何获取Java函数。
static JNINativeMethod nativeUtilsMethods[] = {
{"logInit", "(Ljava/lang/String;Ljava/lang/String;II)V", (void *) localLogInit},
{"logJni", "(ILjava/lang/String;)V", (void *) logJni},
{"logClose", "()V", (void *) logClose},
};
static void nativeLogUtilsRegisterNatives(JNIEnv *jniEnv) {
if (jniEnv == nullptr) {
return;
}
jclass clazz = nullptr;
do {
clazz = jniEnv->FindClass("cn/com/codingce/ndkpractice/utils/LogUtils");
if (clazz == nullptr) {
diagnosis_assert(!"FindClass LogUtils error!");
break;
}
if (jniEnv->RegisterNatives(clazz, nativeUtilsMethods,
std::extent<decltype(nativeUtilsMethods)>::value) != 0) {
diagnosis_assert(!"RegisterNatives error!");
break;
}
} while (false);
if (jniEnv->ExceptionCheck() == JNI_TRUE) {
jniEnv->ExceptionClear();
}
if (clazz != nullptr) {
jniEnv->DeleteLocalRef(clazz);
}
}
重载JNI_OnLoad函数,并在其中调用nativeLogUtilsRegisterNatives函数
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *jniEnv{nullptr};
if (vm->GetEnv((void **) &jniEnv, JNI_VERSION_1_6) != JNI_OK) {
diagnosis_assert(!"JNI version error!");
return JNI_EVERSION;
}
nativeLogUtilsRegisterNatives(jniEnv);
return JNI_VERSION_1_6;
}
更多内容:
Github:https://github.com/xzMhehe Gitee:https://gitee.com/codingce
相关文章
- android图片资源加密,Android平台图像文件加密
- android移动点餐系统内容和要求,基于Android云计算的移动点餐系统
- android 的hook技术,Android Native Hook技术(一)
- strictmode android,Android 应用性能优化-StrictMode(严格模式)
- Android 屏幕适配之框架(AndroidAutoSize)(今日头条)适配
- android autosize原理,Android屏幕适配头条:autosize的原理
- android退出app代码,Android应用退出代码各种方式
- android 模拟器 haxm,Android模拟器不使用HAXM
- android vlc 中文字幕,解决Android版vlc中文乱码问题
- Android中dex文件的加载与优化流程
- android文件访问权限_android最高权限名称
- android toast全屏,Android Toast实现全屏显示
- Android preference_android studio preview
- android调用相册并显示图片_Android获取相册列表
- eclipse中android开发_Android开发教程
- android 复制控件,Android长按复制文本功能[通俗易懂]
- Android进程间通信(一)- Bundle
- 【Android从零单排系列六】《Android视图控件——TextView》
- 【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
- 【错误记录】Flutter / Android 报错 ( AAPT: error: attribute android:requestLegacyExternalStorage not found )
- 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 反汇编二进制机器码 | 打印反汇编数据 )
- 【Android 逆向】函数拦截 ( GOT 表数据结构分析 | 函数根据 GOT 表进行跳转的流程 )
- 【Android Gradle 插件】Gradle 构建机制 ⑤ ( 在 Android Studio 中查看 Android Gradle 插件源码 )
- android Universal Image Loader for Android 说明文档 (1)详解手机开发
- Android Studio 导入项目 出现安装Error:Cause: failed to find target with hash string ‘android-23’ 等错误详解手机开发
- 新品秀:Dell Cast,让Android平板变身台式PC
- Android应用被黑,数百万汽车面临被盗风险
- Android通话记录备份实现代码