JNI异常处理

article/2025/9/14 0:03:30

前言

本文所要介绍的异常处理是指通过JNI调用java层方法时产生的异常处理,并不是指JNI调用Native层函数时产生的异常处理,如果童鞋们想要了解Native层的异常处理可以参考笔者之前的文章《C++之异常处理》

按照java的经验,当发生异常而又没有捕获时,异常后面的代码就得不到继续执行的机会,但是在JNI中不同,在JNI中如果调用java层的方法抛出了异常,依然会继续往后执行,但是这些行为往往会带来各种各样的"惊喜"。。。因此我们需要在异常发生时将这些异常及时进行处理。

本文主要从捕获java层异常、向java层抛出异常两个方面介绍JNI中的异常处理机制。

捕获java层异常

当Native调用java层发生异常时可以通过函数ExceptionOccurred检测是否有发生异常,通过函数ExceptionDescribe输出异常描述信息,如果检测到异常处理完毕或者不进行异常处理又想让程序继续往下执行,那么通过函数ExceptionClear将异常清除即可。

检测是否有异常时还可以使用函数ExceptionCheck,它与ExceptionOccurred函数的作用类似,不同之处在于ExceptionCheck函数不会返回异常对象的引用,而是返回一个异常是否发生的jboolean标识,当返回的标识为JNI_TRUE时代表有异常发生。当调用者不关心异常的类型,仅仅关心是否发生了异常的时候,使用它会更加方便而且高效。

向java层抛出异常

当希望将捕获到的异常向java层继续抛出时,可以通过JNI函数ThrowNew抛出一个异常,这个异常可以被java层的try catch语句块捕获到。

以下是一个在Native层捕获到一个除数为0的异常,并将其抛出给java层的demo:

NumUtils.java

public class NumUtils {public void div(int a,int b){if(b == 0){throw new IllegalArgumentException("除数不能为0");}int c = a/b;}// native函数public native void callByJni();
}

MainActivity.java

public class MainActivity extends AppCompatActivity {static {System.loadLibrary("jnitest");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView textView = findViewById(R.id.sample_text);textView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {NumUtils numUtils = new NumUtils();try {numUtils.callByJni();}catch (Exception e){Log.v("NumUtils","捕获到的异常:" + e.getMessage());}}});}}

native-lib.cpp

extern "C"
JNIEXPORT void JNICALL
Java_com_fly_jnitest_NumUtils_callByJni(JNIEnv *env, jobject thiz) {jclass clazz = env->GetObjectClass(thiz);jmethodID mid = env->GetMethodID(clazz,"div","(II)V");env->CallVoidMethod(thiz,mid,-1,0);jboolean hasException = env->ExceptionCheck();if(hasException == JNI_TRUE){__android_log_print(ANDROID_LOG_DEBUG,"NumUtils","调用java层方法有异常");// 清除异常,不让崩溃env->ExceptionClear();// 抛出异常jclass exceptionClazz = env->FindClass("java/lang/IllegalArgumentException");env->ThrowNew(exceptionClazz,"native层捕获到异常,向java层抛出");env->DeleteLocalRef(exceptionClazz);}
}

小结

1、为了更好地在Native层处理好异常,一般建议在调用CallVoidMethod等一系列函数之后进行异常检测。
2、在设计供Native层调用的函数时尽可能地带上返回值,方便Native层按照返回值判断是否需要处理异常等。
3、当捕获到异常需要提前return程序时需要保证各种资源及时释放。
4、为了简化抛出异常的方法《JNI编程指南》一书中给出了一个工具函数:

void JNU_ThrowByName(JNIEnv *env, const char* name, const char* msg){jclass cls = (*env)->FindClass(env, name);/*if cls is NULL, an exception has already been thrown */if(cls){(*env)->ThrowNew(env, cls, msg);}/* free the local ref */(*env)->DeleteLocalRef(env, cls);
}

系列推荐

JNI基础简介
JNI之数组与字符串的使用
JNI之动态注册与静态注册
JNI之访问java属性和方法
JNI之缓存与引用

关注我,一起进步,人生不止coding!!!
微信扫码关注


http://chatgpt.dhexx.cn/article/baZvCsTC.shtml

相关文章

Python——异常处理

文章目录 异常Python中的异常类捕获与处理异常自定义异常类with语句断言 异常 异常是在程序执行过程中发生的影响程序正常执行的一个事件。异常是Python对象,当Python无法正常处理程序时就会抛出一个异常。一旦Python脚本发生异常,程序需要捕获并处理它…

python异常处理输入不是整数_Python异常处理

异常处理: Python程序运行语法出错会有异常抛出不处理异常会导致程序终止 示例:用户输入一个整数转换成int型,如果用户输入的不是数字而是其他例如字母等则会出现异常 不使用异常处理代码的处理方法 #cat 异常处理.py abc = input("请输入一个数字") if not ab…

ARM的异常处理机制

异常种类 ARM共有如下7种异常模式: 复位(RESET):当处理器复位引脚有效时,系统产生复位异常中断。复位异常中断通常在系统加电和系统复位时发生,直接跳转到复位中断向量处执行称为软复位。未定义的指令(UDE…

spring异常处理

在项目中采用spring的异常处理机制: 示例一、在Controller中加ExceptionHandler注解定义异常拦截的方法,在方法中定义返回的页面: Controller public class ExceptionTestController {ExceptionHandlerpublic String handleException(Excep…

C语言异常处理

文章目录 前言一、 异常表达二、 异常报告三、 异常处理 前言 错误与异常: 错误与异常都是在程序编译或者运行时出现的错误, 不同的是,异常可以被开发人员捕捉和处理;而错误,一般不需要开发人员处理(也无法…

SpringBoot全局异常处理

文章目录 异常处理方案分类基于请求转发基于异常处理器基于过滤器 常见异常处理实现方案1. BasicExceptionController2. ExceptionHandler3. ControllerAdviceExceptionHandler4. SimpleMappingExceptionResolver5. HandlerExceptionResolver6. Filter 全局异常处理实现方案1. …

springboot整合之统一异常处理

特别说明:本次项目整合基于idea进行的,如果使用Eclipse可能操作会略有不同,不过总的来说不影响。 springboot整合之如何选择版本及项目搭建 springboot整合之版本号统一管理 springboot整合mybatis-plusdurid数据库连接池 springboot整合…

C++ 异常处理

目录 一、异常的定义 二、异常的抛出和捕获 1.throw 2.try...catch 3.异常安全 4.异常规范 三、系统预定义异常 四、用户自定义异常 一、异常的定义 异常在C用于错误处理,C语言中一般使用返回值表示错误,C对错误处理进行了扩展,统一使…

关于异常处理的知识整理

目录 1.什么是异常? 2.异常继承结构 3.异常结构继承图 4.关于异常处理的两种方式: 5.异常对象有两个非常重要的方法 1.什么是异常? 程序在执行过程中不正常的情况称为异常,以类和对象的形势存在,可以通过异常类&am…

异常处理---

异常 异常处理 例: public class Demo{public static void main(String[] args) {System.out.println("开始");method();System.out.println("结束");}public static void method(){int[] arr{1,2,3};System.out.println(arr[3]);//数组索引…

异常处理

1.相关概念的介绍 1)异常情形:是指阻止当前方法或作用域继续执行的问题。 2)监控区域:一段可能产生异常的代码,并且后面跟着处理这些异常的代码。 3)try块:如果在方法的内部或者在方法内部调…

异常及异常处理

一、异常的概念 定义: 异常指的是运行期出现的错误,也就是当程序开始执行以后执行期出现的错误。 处理态度: 当捕获到异常以后一定要做出处理,哪怕是把这个异常的错误信息打印出来,这是一种良好的编程习惯。 …

异常处理(throw、throws、try-catch)

Java异常处理的五个关键字try、catch、finally、throw、throws 1.抛出异常throw 在编写程序时,我们必须要考虑程序出现问题的情况。比如,在定义方法时,方法需要接收参数。那么,当调用方法使用接收到的参数时,首先需要…

SpringBoot+Axis2搭建WebService服务端

SpringBootAxis2搭建WebService服务端 之前用过Spring Axis2搭建过WebService项目,网上也有很多资料教程,最近需要在一个SpringBoot项目中添加Axis2的服务端,在网上找了很久,没有找到相关教程,最终经过大神朋友的指点…

AXI(2)完结

四、握手 4.1握手过程 所有的五个通道都是通过相同的VALID/READY握手处理来传输地址、数据和控制信息。 双向握手的机制意味着主机和从机之间传输数据时,都可以控制传输的速率,只有当VALID和READY同时为高电平时,传输才会发生。 发送方&a…

读Axis2用户帮助文档 (axis2中文文档)

作者:李红霞 时间:2006-10-19 声明:本文可以算作Axis2用户手册的翻译,但是翻译后的文本是经过作者理解写出来的,可能有些偏差,欢迎讨论。本文属作者原创,允许转载,但请注明出处。 英…

AXI 3.0 (1)

一、AXI简介 AMBA3.0中新增加了一种总线——AXI(Advanced eXtensible Interface,高级扩展接口)。 AMBA AXI 协议的目标是高性能、高频的系统设计,其包含了若干特性。 适合高带宽和低延迟的设计 提供高频操作,无需使…

Apache axis2 + Eclipse 开发 WebService

一、简介 Apache Axis2是下一代 Apache Axis。Axis2 虽然由 Axis 1.x 处理程序模型提供支持,但它具有更强的灵活性并可扩展到新的体系结构。Axis2 基于新的体系结构进行了全新编写,而且没有采用 Axis 1.x 的常用代码。支持开发 Axis2 的动力是探寻模块化…

Axis2与Web项目整合

一、说明: 上一篇介绍了通过使用Axis2来发布和调用WebService,但是是把WebService发布在Axis2提供的项目中,如果我们需要在自己的Web项目中来使用Axis2发布WebService该怎么做呢? 本篇即介绍在Web项目中使用Axis2来发布WebService. 二、具体…

Axis2中文手册

中文原文 http://tenn.javaeye.com/blog/100736 英文原文 http://ws.apache.org/axis2/1_0/userguide.html 概述 这个说明文档涉及以下内容:  如何使用 axis2 创建 web service 和客户端程序  如何定制一个模块 (Module) 并在 web service 中使用它  Sam…