Chinaunix首页 | 论坛 | 博客
  • 博客访问: 88262
  • 博文数量: 24
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 231
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-13 21:06
个人简介

来也匆匆 几十繁华一阵风; 去也匆匆 回头一看已成空

文章分类

全部博文(24)

文章存档

2016年(4)

2015年(20)

我的朋友

分类: Android平台

2015-12-18 14:58:06

很多情况下,本地代码做JNI调用后都要检查是否有错误发生,本章讲的就是怎么样检查错误和处理错误。

我重点放在JNI函数调用引发的错误上面。如果一个本地方法中调用了一个JNI函数,它必须遵守下面几个步骤来检查和处理这个JNI函数调用时可能引发的错误。至于其它可能的错误,比如本地代码中调用了一个可能引发错误的系统方法,那只需要按照该系统方法的标准文档中规定的来处理就可以了。

6.1 概述

我们通过一些例子来介绍一些JNI异常处理函数

6.1.1 本地代码中如何缓存和抛出异常

下面的代码中演示了如何声明一个会抛出异常的本地方法。CatchThrow这个类声明了一个会抛出IllegalArgumentException异常的名叫doit的本地方法。

class CatchThrow {

     private native void doit() 

         throws IllegalArgumentException;

     private void callback() throws NullPointerException {

         throw new NullPointerException("CatchThrow.callback");

     }

 

     public static void main(String args[]) {

         CatchThrow c = new CatchThrow();

         try {

             c.doit();

         } catch (Exception e) {

             System.out.println("In Java:\n\t" + e);

         }

     }

     static {

         System.loadLibrary("CatchThrow");

     }

 }

Main方法调用本地方法doit,doit方法的实现如下:

JNIEXPORT void JNICALL 

 Java_CatchThrow_doit(JNIEnv *env, jobject obj)

 {

     jthrowable exc;

     jclass cls = (*env)->GetObjectClass(env, obj);

     jmethodID mid = 

         (*env)->GetMethodID(env, cls, "callback", "()V");

     if (mid == NULL) {

         return;

     }

     (*env)->CallVoidMethod(env, obj, mid);

     exc = (*env)->ExceptionOccurred(env);

     if (exc) {

         /* We don't do much with the exception, except that

            we print a debug message for it, clear it, and 

            throw a new exception. */

         jclass newExcCls;

         (*env)->ExceptionDescribe(env);

         (*env)->ExceptionClear(env);

         newExcCls = (*env)->FindClass(env, 

                       "java/lang/IllegalArgumentException");

         if (newExcCls == NULL) {

             /* Unable to find the exception class, give up. */

             return;

         }

         (*env)->ThrowNew(env, newExcCls, "thrown from C code");

     }

 }

运行程序,输出是:

java.lang.NullPointerException:

         at CatchThrow.callback(CatchThrow.java)

         at CatchThrow.doit(Native Method)

         at CatchThrow.main(CatchThrow.java)

 In Java:

         java.lang.IllegalArgumentException: thrown from C code

回调方法抛出一个NullPointerException异常。当CallVoidMethod把控制权交给本地方法时,本地代码会通过ExceptionOccurred来检查这个异常。在我们的例子中,当一个异常被检测到时,本地代码通过调用ExceptionDescribe来输出一个关于这个异常的描述信息,然后通过调用ExceptionClear清除异常信息,最后,抛出一个IllegalArgumentException。

和JAVA中的异常机制不一样,JNI抛出的异常(例如,通过ThrowNew方法)不被处理的话,不会立即终止本地方法的执行。异常发生后,JNI程序员必须手动处理。

阅读(1976) | 评论(0) | 转发(0) |
0

上一篇:android FLAG_ACTIVITY_NEW_TASK

下一篇:Android抓包

给主人留下些什么吧!~~