Android JNI实例代码(二)

我们继续Android JNI开发中的常用代码,第二部分将包含如何在JNI中构造实例化一个Java类以及异常处理的具体方法,有关前一部分的内容可以查看Android JNI实例代码(一) 。

   三、在JNI中构造和实例化Java类

[java]  view plain copy
  1. public class AndroidJniDemo4{  
  2.  public static native void constructClass(); //JNI方法  
  3.  public static void main(String[] args){  
  4.   AndroidJniDemo4.constructClass();  
  5.  }  
  6. }  
  7. class CwjThread implements Runnable {  
  8.  int nCount = 0 ;  
  9.  public void run(){  
  10.   try{  
  11.    Thread.sleep(1987); //休眠1987毫秒  
  12.   }catch(Exception e){  
  13.    e.printStackTrace();  
  14.   }  
  15.   System.out.println("Count="+ nCount);  
  16.  }  
  17. }  

JNI代码:

[cpp]  view plain copy
  1. JNIEXPORT void JNICALL  
  2. Java_AndroidJniDemo4_constructClass(JNIEnv *env, jclass clazz){  
  3.  jclass jclazz , cwjclazz;   
  4.  jmethodID mid , mid2 , runmid ;  
  5.    
  6.  jobject obj , obj2 ;  
  7.  jclazz = (*env)->FindClass(env, "CwjThread");   //查找Java层的类  
  8.  if (jclazz == NULL)  
  9.  {  
  10.   return ;  
  11.  }  
  12.  mid = (*env)->GetMethodID(env, jclazz,"<init>""()V"); //构造CwjThread类  
  13.    
  14.  if (mid == NULL)  
  15.  {  
  16.   return ;  
  17.  }  
  18.  obj = (*env)->NewObject(env, jclazz, mid, NULL); //创建该类的实例,生成的新对象为obj  
  19.  cwjclazz = (*env)->FindClass(env, "Ljava/lang/Thread;"); 得到Thread类  
  20.  if (cwjclazz == NULL)  
  21.  {  
  22.   return ;  
  23.  }   
  24.    
  25.  mid2 = (*env)->GetMethodID(env, cwjclazz,"<init>""(Ljava/lang/Runnable;)V"); //获取Runnable方法ID  
  26.    
  27.  if (mid2 == NULL)  
  28.  {  
  29.   return ;  
  30.  }  
  31.  obj2 = (*env)->NewObject(env, cwjclazz, mid2, obj);  //构造Runnable对象  
  32.  runmid = (*env)->GetMethodID(env, cwjclazz,"start""()V");  //获取Runable对象的start方法ID  
  33.    
  34.  if (runmid == NULL)  
  35.  {  
  36.   return ;  
  37.  }  
  38.  (*env)->CallVoidMethod(env, obj2, runmid);   //执行start方法在JNI中,来启动线程  
  39.  (*env)->DeleteLocalRef(env, jclazz);  //我们并没有使用NewLocalRef有关本地引用的内容Android123在 Android JNI开发终极篇中将详细讲述  
  40. }  

上面的代码可能我们发现JNI中构造一个类比Java层麻烦的多,需要先获取ID,测试是否为空,然后编写类方法的构造和类型签名符号,多了很多这样的操 作,不过Android开发网提醒大家毕竟JNI中没有类的声明引用,只有动态获取这些方法的ID所以执行效率可能比Java还有所降低,类似Java反 射一样的处理机制,希望大家明白这个道理。

 

四、JNI中的异常处理实例代码

[java]  view plain copy
  1. class AndroidJniDemo5 {  
  2.  private native void createException() throws IllegalArgumentException; //JNI中抛出一个参数不合法异常  
  3.  private void throwException() throws NullPointerException {  
  4.   throw new NullPointerException("Java error, android123 "); //Java中产生一个空指针异常  
  5.  }  
  6.  public static void main(String args[]) {  
  7.   AndroidJniDemo5 ajd5 = new AndroidJniDemo5();  
  8.   try {  
  9.    ajd5.createException();   
  10.   } catch (Exception e) {  
  11.      e.printStackTrace();  
  12.   }  
  13.  }  
  14.  static {  
  15.   System.loadLibrary("AndroidJniDemo5");  
  16.  }  
  17. }  

下面的JNI中的异常具体代码

[cpp]  view plain copy
  1. JNIEXPORT void JNICALL  
  2. Java_AndroidJniDemo5_createException(JNIEnv *env, jobject obj)  
  3. {  
  4.  jthrowable throwable;  
  5.  jclass clazz = (*env)->GetObjectClass(env, obj);  
  6.  jmethodID mid = (*env)->GetMethodID(env, clazz, "throwException""()V"); //获取Java中的throwException方法ID  
  7.  if (mid == NULL)  
  8.  {  
  9.   return;  
  10.  }  
  11.  (*env)->CallVoidMethod(env, obj, mid); //执行throwException方法  
  12.  throwable = (*env)->ExceptionOccurred(env);  //有异常发生,其实Android123提醒大家还可以使用JNI中的异常检测ExceptionCheck函数来判断  
  13.  if (throwable)  // 如果发生了异常  
  14.  {  
  15.   jclass newExceptionClazz;  
  16.   (*env)->ExceptionDescribe(env);  
  17.   (*env)->ExceptionClear(env);  
  18.   newExceptionClazz = (*env)->FindClass(env,"java/lang/IllegalArgumentException"); //实例化一个参数不合法异常  
  19.   if (newExceptionClazz == NULL)  
  20.   {  
  21.    return;  
  22.   }  
  23.   (*env)->ThrowNew(env, newExceptionClazz, "JNI cwj exception"); //在JNI中抛出异常  
  24.  }  
  25. }  

 最后我们可以看到在JNI中处理很多事情确实需要编写很多代码,同时有关类的构造符号什么的,目前的IDE和编译器无法检查,所以Android开发网 提醒大家一定要记住Java签名符号的格式和规范,下一次我们给出一些例子,帮助Android NDK初学者快速了解JNI的规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值