热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidJNI开发系列:第四章异常处理

项目代码:https:github.comVincentWei95ndkAndroidJNI开发系列:第一章JNIEnv接口指针AndroidJNI

项目代码:https://github.com/VincentWei95/ndk

Android JNI开发系列:第一章 JNIEnv接口指针

Android JNI开发系列:第二章 数据类型

Android JNI开发系列:第三章 对引用数据类型的操作

Android JNI开发系列:第四章 异常处理

Android JNI开发系列:第五章 局部和全局引用

Android JNI开发系列:第六章 线程

Android JNI开发系列:第七章 POSIX线程

Android JNI开发系列:第八章 POSIX Socket API 面向连接的通信

Android JNI开发系列:第九章 POSIX Socket API 无连接的通信

Android JNI开发系列:第十章 POSIX Socket API 本地通信

在java中,当抛出一个异常时,虚拟机停止执行代码块并进入调用栈反向检查能处理特定类型异常的异常处理程序代码块,也就是捕获异常。虚拟机清除异常并将控制权交给异常处理程序。

相比之下,JNI要求开发人员在异常发生后显示地实现异常处理流。


1 捕获异常

public class JavaClass {// 调用throwingMethod()时从JNI中捕获异常private void throwingMethod() throws NullPointException {throw new NullPointException();}private native void accessMethods();
}jthrowable ex;
...
(*env)->CallVoidMethod(env, instance, throwingMethodId);// JNI提供了ExceptionOccurred函数查询虚拟机中是否有挂起的异常
ex = (*env)->ExceptionOccurred(env);
if (ex != 0) {// 使用完之后ExceptionClear函数清除异常(*env)->ExceptionClear(env);
}

2 抛出异常

因为异常是java类,应该先用FindClass函数找到异常类,再用 ThrowNew 函数初始化抛出异常。

jclazz clazz;
...
clazz = (*env)->FindClass(env, "java/lang/NullPointerException");
if (clazz != 0) {(*env)->ThrowNew(env, clazz, "Exception message");
}

注意:因为原生函数代码执行不受虚拟机控制,因此抛出异常并不会停止原生函数的执行并把控制权转交给异常处理程序。所以在原生代码抛出异常时,应该释放所有已分配的原生资源。


3 异常demo


  • com_example_ndk_JNITest.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_ndk_JNITest */#ifndef _Included_com_example_ndk_JNITest
#define _Included_com_example_ndk_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/** Class: com_example_ndk_JNITest* Method: accessExceptionMethod* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_example_ndk_JNITest_accessExceptionMethod(JNIEnv *, jobject);/** Class: com_example_ndk_JNITest* Method: throwExceptionMethod* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_example_ndk_JNITest_throwExceptionMethod(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif

  • com_example_ndk_JNITest.c

#include "/include/com_example_ndk_JNITest.h"
#include <jni.h>
#include <stdio.h>
#include <syslog.h>/** Class: com_example_ndk_JNITest* Method: accessExceptionMethod* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_example_ndk_JNITest_accessExceptionMethod(JNIEnv *env, jobject object) {// 获取java classjclass clazz &#61; (*env)->GetObjectClass(env, object);// 获取class中的方法idjmethodID methodId &#61; (*env)->GetMethodID(env, clazz, "throwingExceptionMethod", "()V");// 调用java中的方法(*env)->CallVoidMethod(env, object, methodId);// 检查调用的方法是否发生异常jthrowable exception &#61; (*env)->ExceptionOccurred(env);if (exception !&#61; 0) {// 函数发生异常&#xff0c;检查完后清除异常syslog(LOG_ERR, "native catch exception");(*env)->ExceptionClear(env);}
}/** Class: com_example_ndk_JNITest* Method: throwExceptionMethod* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_example_ndk_JNITest_throwExceptionMethod(JNIEnv *env, jobject object) {jclass exceptionClazz &#61; (*env)->FindClass(env, "java/lang/NullPointerException");if (exceptionClazz !&#61; 0) {(*env)->ThrowNew(env, exceptionClazz, "native throw null pointer exception!");}
}

  • JNITest.java

package com.example.ndk;public class JNITest {// 抛出异常方法private void throwingExceptionMethod() {throw new NullPointerException("native access throw null pointer exception!");}static {System.loadLibrary("ndk");}public native void accessExceptionMethod();public native void throwExceptionMethod();
}

  • JniActivity.java

package com.example.ndk;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {&#64;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);JNITest jniTest &#61; new JNITest();jniTest.accessExceptionMethod();try {jniTest.throwExceptionMethod();} catch (Exception e) {e.printStackTrace();}}
}

推荐阅读
  • 标题: ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的步骤和方法
    本文介绍了在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的详细步骤和方法。首先需要下载最新的Java SE Development Kit 9发行版,然后按照给出的Shell命令行方式进行安装。详细的步骤和方法请参考正文内容。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
author-avatar
欧阳火凡
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有