您现在的位置是:首页 > 正文

Android JNI学习-异常处理

2024-01-30 21:25:12阅读 0

异常我们已经很熟悉了,空指针、数组越界等等,在Java中,当抛出一个异常,虚拟机会停止执行代码块并进入调用栈反向检查能处理特定异常的异常处理程序代码块,虚拟机清除异常并将控制权交给异常处理程序。而JNI不同,JNI没有像Java一样有try…catch…final这样的异常处理机制,面且在本地代码中调用某个JNI接口时如果发生了异常,后续的本地代码不会立即停止执行,而会继续往下执行后面的代码,这就要求开发人员在异常发生后显式地实现异常处理。

1 捕获异常

在一个方法执行之后,可以调用(*env)->ExceptionCheck或者 (*env)->ExceptionOccurred(两者的区别在于返回值不一样)

ExceptionCheck:检查是否发生了异常,若有异常返回JNI_TRUE,否则返回JNI_FALSE ExceptionOccurred:检查是否发生了异常,若用异常返回该异常的引用,否则返回NULL

     const jchar *cstr = (*env)->GetStringChars(env, jstr);
     if (c_str == NULL) {
         return; 
     }
     if ((*env)->ExceptionCheck(env)) { /* 异常检查 */
         (*env)->ReleaseStringChars(env, jstr, cstr); // 发生异常后释放分配内存
         return; 
     }
复制代码

2 抛出异常

ThrowNew:在当前线程触发一个异常,并自定义输出异常信息 jint (JNICALL *ThrowNew) (JNIEnv *env, jclass clazz, const char *msg);

Throw:丢弃一个现有的异常对象,在当前线程触发一个新的异常 jint (JNICALL *Throw) (JNIEnv *env, jthrowable obj);

FatalError:致命异常,用于输出一个异常信息,并终止当前VM实例(即退出程序) void (JNICALL *FatalError) (JNIEnv *env, const char *msg);

3 示例

jclass jclass1 = (*env)->FindClass(env, "com/test/JNIController");
    if (jclass1 == 0) {
        return;
    }

    jmethodID methodID = (*env)->GetMethodID(env, jclass1, "exitProcessCallBack", "(III)V");
    if (methodID == 0) {
        return;
    }

    (*env)->CallVoidMethod(env, local_object, methodID, code, uploaded, all);

    if ((*env)->ExceptionCheck){
        (*env)->ExceptionDescribe(env);     // 打印异常的堆栈信息 
        (*env)->ExceptionClear(env);        // 清除异常堆栈信息 
        (*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"JNI出现异常!");
    }
复制代码

4 总结

  1. 当调用一个JNI函数后,必须先检查、处理、清除异常后再做其它 JNI 函数调用,否则会产生不可预知的结果。
  2. 一旦发生异常,立即返回,让调用者处理这个异常。或 调用 ExceptionClear 清除异常,然后执行自己的异常处理代码。

网站文章

  • Kafka学习笔记之K8S内filebeat传输到kafka报错带解决方案

    Kafka学习笔记之K8S内filebeat传输到kafka报错带解决方案

    0x00 概述filebeat非常轻量级,正常情况下占用的资源几乎都能忽略不计,但是部署后发现资源占用很大,所以怀疑是filebeat本身出了问题。第一时间查看filebeat日志(默认路径/var/log/filebeat/filebeat,K8S需要在控制台实时查看pod的日志),发现有大量内容输出:2019-03-20T08:55:02.198+0800 IN...

    2024-01-30 21:25:07
  • PgSQL · 追根究底 · WAL日志空间的意外增长

    PgSQL · 追根究底 · WAL日志空间的意外增长

    问题出现我们在线上巡检中发现,一个实例的pg_xlog目录,增长到4G,很是疑惑。刚开始怀疑是日志归档过慢,日志堆积在pg_xlog目录下面,未被清除导致。于是检查归档目录下的文件,内容如下。但发现新近完成写入的日志文件都被归档成功了(即在pg_xlog/archive_status里面,有对应的xxx.done文件)。ls -lrt pg_xlog...-rw------- ...

    2024-01-30 21:24:38
  • 第七节:元组&字典

    元组和字典for循环range函数元组字典的简介字典的增删改查作业 for循环 range函数 元组 字典的简介 字典的增删改查 作业

    2024-01-30 21:24:32
  • java构造一个银行账户类

    java构造一个银行账户类

    (1)思路数据成员用户的账户名称、用户的账户余额(private数据类型)方法包括开户(设置账户名称及余额),利用构造方法完成查询余额。取款存款(2)代码实现package p1;import jav...

    2024-01-30 21:24:25
  • JDK和Maven在Windows下安装和配置

    JDK和Maven在Windows下安装和配置

    文章目录1.JDK1.1 下载安装1.2 配置环境变量1.3 验证安装2.Maven2.1 下载安装2.2 配置环境变量2.3 修改本地仓库位置2.4 配置阿里云的中央仓库2.5 验证和测试1.JDK...

    2024-01-30 21:23:55
  • bzoj2242

    2242: [SDOI2011]计算器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 3179 Solved: 1248 [Submit][Status][Discuss] Description 你被要求设计一个计算器完成以下三项任务: 1、给定y,z,p,计算Y^Z Mod P 的值; 2、给定y,z,p,计算满足xy≡

    2024-01-30 21:23:48
  • JS逆向混淆加密参数分析,反调试分析

    JS逆向混淆加密参数分析,反调试分析

    闲逛github看到issues别人发的一个网站,网址:http://ys.fgj.taiyuan.gov.cn/Firsthand/tyfc/publish/p/ProjectList.do 随便勾选菜单查询,上抓包 如下图requestbody 分析一下requestbody的生成过程,老规矩F12 匿名函数的无限debugger,直接删掉debugger代码即可,有2个debugger...

    2024-01-30 21:23:40
  • 实现每日早安推送

    实现每日早安推送

    做一个程序员给女朋友的浪漫礼物吧,微信推送每日早安。

    2024-01-30 21:23:10
  • Linux环境下使用阿里云盘 热门推荐

    Linux环境下使用阿里云盘 热门推荐

    一直有个直播推流的想法,那就是把阿里云盘上的视频资源,在不下载到本地的情况下放在服务器上直播推流,这个时候就需要阿里云盘能能支持Linux环境下使用了。 目前阿里云盘官方还没有推出Linux环境下的版...

    2024-01-30 21:23:03
  • 软件测试常用的oracle语句,Oracle 一些常用的语句记录

    1、oracle数据库锁表查询:select db.object_name,sess.sid,sess.serial#,sess.module,sess.action ,'alter system k...

    2024-01-30 21:22:54