JNI异常处理
来源:互联网 发布:网络攻防渗透 编辑:程序博客网 时间:2024/06/05 07:43
本地代码中如何缓存和抛出异常
根据一个例子来介绍:
1.新建一个CatchThrow.Java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2.JNI实现
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
3.Java中调用
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
4.输出结果:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
制作一个抛出异常的工具函数
抛出一个异常通常需要两步:
1.通过FindClass找到异常类
2.调用ThrowNew函数生成异常。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
JNU_ThrowByName 这个工具函数首先使用 FindClass 函数来找到异常类,如果 FindClass 执行失败(返回 NULL),VM 会抛出一个异常(比如 NowClassDefFoundError),这种情况下 JNI_ThrowByName 不会再抛出另外一个
异常。如果 FindClass 执行成功的话,我们就通过 ThrowNew 来抛出一个指定名 字的异常。当函数 JNU_ThrowByName 返回时,它会保证有一个异常需要处理,但 这个异常不一定是 name 参数指定的异常。当函数返回时,记得要删除指向异常 类的局部引用。向 DeleteLocalRef 传递 NULL 不会产生作用。
异常处理
异常检查
检查异常有两种方式:
1.大部分JNI函数会通过特定的返回值(NULL)来表示已经发生了一个错误,并且当前线程中又一个异常需要处理。在C语言中,用返回值来标识错误信息是一个很常见的方式。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
2.当一个JNI函数返回一个明确的错误码时,可以用ExceptionCheck来检查是否有异常发生。但是,用返回的错误码来判断比较高效。一旦JNI函数的返回值是一个错误码,那么接下来调用ExceptionCheck肯定会返回JNI_TRUE。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
异常处理
本地代码通常有两种方式来处理一个异常:
1.一旦发生异常,立即返回,让调用者处理这个异常。
2.通过ExceptionClear清除异常,然后执行自己的异常处理代码。
当一个异常发生后,必须先检查、处理、清除异常后再做其他JNI函数调用,否则的话,结果未知。
通常来说,当有一个未处理的异常时,你只可以调用两种JNI函数:异常处理和清除VM资源的函数。
当异常发生时,释放资源是一件很重要的事。比如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
工具函数中的异常
编写工具函数时,要把工具函数内部分发生的异常传播到调用它的方法中。
这里有两个方法:
1.对调用者来说,工具函数提供一个错误返回码比简单地把异常传播过去更方便一些。
2.工具函数在发生异常时尤其需要注意管理局部引用的方式。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
JNU_CallMethodByName 的参数当中有一个 jboolean 指针,如果函数执行成功的 话,指针指向的值会被设置为 JNI_TRUE,如果有异常发生的话,会被设置成 JNI_FALSE。这就可以让调用者方便地检查异常。
JNU_CallMethodByName 首先通过 EnsureLocalCapacity 来确保可以创建两个局 部引用,一个类引用,一个返回值。接下来,它从对象中获取类引用并查找方法 ID。根据返回类型,switch 语句调用相应的 JNI 方法调用函数。回调过程完成 后,如果 hasException 不是 NULL,我们调用 ExceptionCheck 检查异常。 函数 ExceptionCheck 和 ExceptionOccurred 非常相似,不同的地方是,当有异 常发生时,ExceptionCheck 不会返回一个指向异常对象的引用,而是返回 JNI_TRUE,没有异常时,返回 JNI_FALSE。而 ExceptionCheck 这个函数不会返 回一个指向异常对象的引用,它只简单地告诉 地代码是否有异常发生。上面的 代码如果使用 ExceptionOccurred 的话,应该这么写:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
为了删除指向异常对象的局部引用,DeleteLocalRef 方法必须被调用。 使用 JNU_CallMethodByName 这个工具函数,我们可以重写 Instance-MethodCall.nativeMethod 方法的实现:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
调用 JNU_CallMethodByName 函数后,我们不需要检查异常,因为 地方法后面 会立即返回。
- JNI异常的处理
- JNI异常的处理
- JNI异常的处理
- jni的异常处理
- JNI异常处理
- JNI异常处理
- JNI异常处理
- JNI异常处理
- JNI异常处理
- NDK/JNI异常处理
- JNI异常处理
- JNI异常处理
- Android JNI抛出异常处理
- JNI由浅入深_9_JNI 异常处理
- JNI数组传递与异常处理
- JNI数组传递与异常处理
- JNI数组传递与异常处理
- JNI数组传递与异常处理
- Python 异常处理
- linux安装中文帮助文档
- SQL Server使用2G以上内存设置方法
- MyBatis 查询映射自定义枚举
- .net Redis缓存服务搭建及实现数据读写
- JNI异常处理
- LigerUI
- centos6.8 64 安装 mysql5.7
- cookie 和session 的区别详解
- python+opencv 读取文件夹下的所有图像并批量保存ROI
- 用Maven创建第一个web项目 (好文章忍不住把保存下来)
- springboot导入xml
- NestedScrolling机制学习(一)
- Webpack如何打包才能尽可能的缩小体积(详解)