当前位置: 首页 > news >正文

jni理解

  1. 定义 JNI 方法映射表(注册表)
    对应原文件中的 sScreenCaptureMethods 数组,用于声明 Java native 方法与 C++ 函数的映射关系:
// ... 其他代码(如结构体定义、工具函数)...// ----------------------------------------------------------------------------// JNI 方法映射表(动态注册核心)
static const JNINativeMethod sMyDynamicMethods[] = {// { Java层native方法名, 方法签名, C++函数指针 }{"nativeAddNumbers", "(II)I", (void*)nativeAddNumbers},          // 示例1:两数相加{"nativeGetDeviceInfo", "()Ljava/lang/String;", (void*)nativeGetDeviceInfo}, // 示例2:获取设备信息
};// ... 后续注册函数 ...
  1. 实现 C++ 函数
// ... 其他代码 ...// 示例1:两数相加(对应 Java 的 nativeAddNumbers(int a, int b))
static jint nativeAddNumbers(JNIEnv* env, jclass clazz, jint a, jint b) {return a + b; // 简单业务逻辑
}// 示例2:获取设备信息(对应 Java 的 nativeGetDeviceInfo())
static jstring nativeGetDeviceInfo(JNIEnv* env, jclass clazz) {std::string info = "Model: RK3576; SDK: 33"; // 模拟设备信息return env->NewStringUTF(info.c_str()); // 返回 Java String
}// ... JNI 方法映射表(见步骤1)...
  1. 实现注册函数
    对应原文件中的 register_android_window_ScreenCapture 函数,将映射表注册到 JVM:
// ... JNI 方法映射表(见步骤1)...// 注册函数:将 sMyDynamicMethods 映射表注册到 Java 类
int register_com_example_MyDynamicJni(JNIEnv* env) {// 1. 指定 Java 类全路径(需与 Java 层包名+类名一致)const char* javaClassName = "com/example/MyDynamicJni";// 2. 注册映射表(通过 RegisterMethodsOrDie 完成注册)int err = RegisterMethodsOrDie(env, javaClassName,                // Java 类名sMyDynamicMethods,            // JNI 方法映射表NELEM(sMyDynamicMethods)      // 映射表长度(自动计算元素个数));// 3. (可选)初始化 Java 类的字段/方法 ID(如原文件中的 gCaptureArgsClassInfo)jclass myClass = FindClassOrDie(env, javaClassName);// ... (如需操作 Java 对象字段,可在此获取 fieldID/methodID)...return err; // 返回注册结果(0 表示成功)
}} // namespace android
  1. Java 层配套代码(需手动编写)
    动态注册需对应 Java 类中声明 native 方法,例如 MyDynamicJni.java
package com.example;public class MyDynamicJni {// 加载 native 库(对应编译生成的 libxxx.so)static {System.loadLibrary("my_dynamic_jni"); // 库名需与 Android.bp 中定义一致}// 声明 native 方法(方法名、参数、返回值需与 JNI 映射表完全匹配)public native int nativeAddNumbers(int a, int b);public native String nativeGetDeviceInfo();// 测试调用public static void main(String[] args) {MyDynamicJni jni = new MyDynamicJni();System.out.println("1+2=" + jni.nativeAddNumbers(1, 2)); // 输出 3System.out.println("Device Info: " + jni.nativeGetDeviceInfo()); // 输出设备信息}
}
原文件关键元素示例对应部分作用说明
sScreenCaptureMethodssMyDynamicMethods定义 Java 方法名与 C++ 函数的映射关系,无需依赖 Java_xxx 命名规则
nativeCaptureDisplaynativeAddNumbersC++ 业务逻辑的具体实现,函数名可自定义(通过映射表与 Java 方法关联)
register_android_window_ScreenCaptureregister_com_example_MyDynamicJni将映射表注册到虚拟机,完成 Java 与 C++ 方法的绑定

为什么需要动态注册?

  1. 灵活命名:C++ 函数名无需遵循冗长的 Java_包名_类名_方法名 格式(如原文件中直接使用 nativeCaptureDisplay,而非 Java_android_window_ScreenCapture_nativeCaptureDisplay)。

  2. 批量管理:通过映射表统一管理所有 native 方法,便于维护(如原文件中 sScreenCaptureMethods 集中声明了 6 个方法映射)。

  3. 性能优化:动态注册比静态注册(依赖虚拟机查找函数名)效率更高,尤其适合系统框架层存在大量 JNI 方法的场景

http://www.lryc.cn/news/604940.html

相关文章:

  • 网络编程-(网络计算机和网络通信)
  • Adobe Illustrator安装下载教程(附安装包)Illustrator2025
  • 【异世界历险之数据结构世界(冒泡、选择、快速排序)】
  • 数据结构(7)单链表算法题OVA
  • LLM 模型部署难题的技术突破:从轻量化到分布式推理的全栈解决方案
  • 【数据结构初阶】--二叉树(五)
  • 数据结构——单链表1
  • jmeter读取上游接口并遍历数组数据并进行压测
  • Vulnhub靶场:ica1
  • 【网络运维】 Linux:使用 Cockpit 管理服务器
  • IO复用实现并发服务器
  • 2025年7月技术问答第6期
  • 无人机入门--个人笔记
  • 电力设施通道防外破防异物实时监控预警装置的核心功能是什么
  • C 语言与 C++、Java、Python 等编程语言的区别
  • 国产音频DA转换芯片DP7361支持192K六通道24位DA转换器
  • Android RTMP推送|轻量级RTSP服务同屏实践:屏幕+音频+录像全链路落地方案
  • 工业计算机ARM-如何实现工业数字化升级EC100!
  • 论文阅读|NeurIPS 2024|Mamba进一步研究|MSVMamba
  • 原生微信小程序实现语音转文字搜索---同声传译
  • NAT技术与代理服务
  • SNR-Aware Low-light Image Enhancement 论文阅读
  • 【网络工程师软考版】路由协议 + ACL
  • 15、点云<—>深度图转换原理
  • rabbitmq--默认模式(点对点)
  • 【深度学习新浪潮】3D城市建筑多样化生产的研发进展调研
  • vulhub-Thales靶机练习
  • STL学习(?、常用的算数算法和集合算法)
  • SAP-ABAP:SAP ABAP OpenSQL JOIN 操作权威指南高效关联多表数据
  • xxljob-快速上手