一、捕获异常

异常处理是Java中的功能,在Android中使用SDK进行开发的时候经常要用到。Android原生代码在执行过程中如果遇到错误,需要检测,并抛出异常给Java层。执行原生代码出现了问题,例如使用了空指针、内存泄漏,并且没有做相应的检测盒异常抛出,APP会马上闪退,没有任何提示。

JNI中的异常处理和Java的不一样。Java中的异常处理,是直接捕获,然后做相应的处理。JNI要求开发人员在异常发生之后显式实现异常处理流。例如以下例子:

  1. public class JavaClass {
  2. /**
  3. * 异常抛出方法
  4. */
  5. private void throwException() throws NullPointerException {
  6. throw new NullPointerException("Null pointer");
  7. }
  8. /**
  9. * 原生方法
  10. */
  11. private native void nativeMethod();
  12. }

在原生方法nativeMethod中调用throwException方法,nativeMethod原生方法需要显示地做异常处理。JNI提供了ExceptionOccurred函数查询虚拟机是否有挂起的异常。在使用完之后,还需要ExceptionClear函数显式地清除异常。

  1. jthrowable ex;
  2. //...
  3. (*env)->CallVoidMethod(env, instance, throwExceptionId);
  4. ex = (*env)->ExceptionOccurred(env);
  5. if (0 != ex) {
  6. (*env)->ExceptionClear(env);
  7. }

二、抛出异常

JNI也允许原生代码抛出异常。由于异常是Java的类,所以在JNI中需要用FindClass函数找到异常类,用ThrowNew函数就可以初始化并抛出新的异常。例如:

  1. jclass clazz;
  2. //...
  3. clazz = (*env)->FindClass(env, "java/lang/NullPointerException");
  4. if (0 != clazz) {
  5. (*env)->ThrowNew(env, clazz, "Exception message.");
  6. }

因为原生方法不受虚拟机的控制,所以抛出的异常并不会停止原生方法的执行。在抛出异常的时候,需要释所有已经分配的资源,例如内存资源...通过JNIEnv接口获得的局部引用,在原生方法返回之后会被虚拟机自动释放。

Android NDK开发篇:Java与原生代码通信(异常处理)的更多相关文章

  1. Android NDK开发篇(六):Java与原生代码通信(异常处理)

    一.捕获异常 异常处理是Java中的功能.在Android中使用SDK进行开发的时候常常要用到.Android原生代码在运行过程中假设遇到错误,须要检測,并抛出异常给Java层.运行原生代码出现了问题 ...

  2. Android NDK开发篇(四):Java与原生代码通信(原生方法声明与定义与数据类型)

    Java与原生代码通信涉及到原生方法声明与定义.数据类型.引用数据类型操作.NIO操作.訪问域.异常处理.原生线程 1.原生方法声明与定义 关于原生方法的声明与定义在上一篇已经讲一点了,这次具体分析一 ...

  3. Android NDK开发篇:Java与原生代码通信(原生方法声明与定义与数据类型)

    Java与原生代码通信涉及到原生方法声明与定义.数据类型.引用数据类型操作.NIO操作.访问域.异常处理.原生线程 1.原生方法声明与定义 关于原生方法的声明与定义在上一篇已经讲一点了,这次详细分析一 ...

  4. Android NDK开发篇(五):Java与原生代码通信(数据操作)

    尽管说使用NDK能够提高Android程序的运行效率,可是调用起来还是略微有点麻烦.NDK能够直接使用Java的原生数据类型,而引用类型,由于Java的引用类型的实如今NDK被屏蔽了,所以在NDK使用 ...

  5. Android NDK开发篇:Java与原生代码通信(数据操作)

    虽然说使用NDK可以提高Android程序的执行效率,但是调用起来还是稍微有点麻烦.NDK可以直接使用Java的原生数据类型,而引用类型,因为Java的引用类型的实现在NDK被屏蔽了,所以在NDK使用 ...

  6. Android NDK开发(五)--C代码回调Java代码【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41862479 在上篇博客里了解了Java层是怎样传递数据到C层代码,并且熟悉了大部 ...

  7. Android NDK开发篇:如何使用JNI中的global reference和local reference

    JNI提供了一些实例和数组类型(jobject.jclass.jstring.jarray等)作为不透明的引用供本地代码使用.本地代码永远不会直接操作引用指向的VM内部的数据内容.要进行这些操作,必须 ...

  8. Android NDK 开发(四)java传递数据到C【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处 ...

  9. Android NDK开发 JNI操作java构造方法,普通方法,静态方法(七)

    Android NDK开发 JNI操作java普通.静态.构造方法 1.Jni实例化一个Java类的实例jobject 1.通过FindClas( ),获取Java类的的jclass 2.通过GetM ...

随机推荐

  1. 【Python小试】计算目录下所有DNA序列的Kmer并过滤

    背景 Kmer是基因组组装算法中经常接触到的概念,简单来说,Kmer就是长度为k的核苷酸序列.一般长短为m的reads可以分成m-k+1个Kmer.Kmer的长度和阈值直接影响到组装的效果. Deno ...

  2. LearnPython_week3

    函数说明 1 # -*- coding:utf-8 -*- 2 # Author:Wong Du 3 4 5 ###函数, 6 # 能避免代码重复, 7 # 方便代码修改等操作 8 def wong( ...

  3. 疯了吧!这帮人居然用 Go 写“前端”?(一)

    作者 | 郑嘉涛(羣青) 来源 | 尔达 Erda 公众号 ​ 无一例外,谈到前后端分离"必定"是 RESTful API,算是定式了.但我们知道 REST 在资源划分上的设计总是 ...

  4. day29并发编程

    day29并发编程 1.进程锁 一.使用锁维护执行顺序 代码: from multiprocessing import Process,Lock import os import time def t ...

  5. 爬虫系列:存储 CSV 文件

    上一期:爬虫系列:存储媒体文件,讲解了如果通过爬虫下载媒体文件,以及下载媒体文件相关代码讲解. 本期将讲解如果将数据保存到 CSV 文件. 逗号分隔值(Comma-Separated Values,C ...

  6. 求最长子序列(非连续)的STL方法 - 洛谷P1020 [NOIP1999 普及组] 导弹拦截

    先给出例题:P1020 [NOIP1999 普及组] 导弹拦截 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 大佬题解:P1020 [NOIP1999 普及组] 导弹拦截 - 洛谷 ...

  7. 容器之分类与各种测试(三)——stack

    stack是栈,其实现也是使用了双端队列(只要不用双端队列的一端,仅用单端数据进出即完成单端队列的功能),由于queue和stack的实现均是使用deque,没有自己的数据结构和算法,所以这俩也被称为 ...

  8. canal整合springboot实现mysql数据实时同步到redis

    业务场景: 项目里需要频繁的查询mysql导致mysql的压力太大,此时考虑从内存型数据库redis里查询,但是管理平台里会较为频繁的修改增加mysql里的数据 问题来了: 如何才能保证mysql的数 ...

  9. Oracle 创建 md5 加密函数

    使用 Oracle 的 utl_raw.DBMS_OBFUSCATION_TOOLKIT 可以获取 md5 加密字符串: select utl_raw.cast_to_raw(DBMS_OBFUSCA ...

  10. 【编程思想】【设计模式】【结构模式Structural】适配器模式adapter

    Python版 https://github.com/faif/python-patterns/blob/master/structural/adapter.py #!/usr/bin/env pyt ...