Android JNI執行個體代碼(二)

來源:互聯網
上載者:User
聲明:本文轉載自android開發網

   我們繼續Android JNI開發中的常用代碼,第二部分將包含如何在JNI中構造執行個體化一個Java類以及異常處理的具體方法,有關前一部分的內容可以查看 Android JNI執行個體代碼(一)  。

   三、在JNI中構造和執行個體化Java類

 public class AndroidJniDemo4{
 public static native void constructClass(); //JNI方法
 public static void main(String[] args){
  AndroidJniDemo4.constructClass();
 }
}

class CwjThread implements Runnable {
 int nCount = 0 ;
 public void run(){
  try{
   Thread.sleep(1987); //休眠1987毫秒
  }catch(Exception e){
   e.printStackTrace();
  }
  System.out.println("Count="+ nCount);
 }
}

JNIEXPORT void JNICALL
Java_AndroidJniDemo4_constructClass(JNIEnv *env, jclass clazz){
 jclass jclazz , cwjclazz;  
 jmethodID mid , mid2 , runmid ;
 
 jobject obj , obj2 ;

 jclazz = (*env)->FindClass(env, "CwjThread");   //尋找Java層的類

 if (jclazz == NULL)
 { 
  return ; 
 }

 mid = (*env)->GetMethodID(env, jclazz,"<init>", "()V"); //構造CwjThread類
 
 if (mid == NULL)
 { 
  return ; 
 }

 obj = (*env)->NewObject(env, jclazz, mid, NULL); //建立該類的執行個體,產生的新對象為obj

 cwjclazz = (*env)->FindClass(env, "Ljava/lang/Thread;"); ////得到Thread類

 if (cwjclazz == NULL) 
 { 
  return ; 
 } 
 
 mid2 = (*env)->GetMethodID(env, cwjclazz,"<init>", "(Ljava/lang/Runnable;)V"); //擷取Runnable方法ID
 
 if (mid2 == NULL) 
 {
  return ; 
 }

 obj2 = (*env)->NewObject(env, cwjclazz, mid2, obj);  //構造Runnable對象

 runmid = (*env)->GetMethodID(env, cwjclazz,"start", "()V");  //擷取Runable對象的start方法ID
 
 if (runmid == NULL) 
 { 
  return ; 
 }

 (*env)->CallVoidMethod(env, obj2, runmid);   //執行start方法在JNI中,來啟動線程

 (*env)->DeleteLocalRef(env, jclazz);  //我們並沒有使用NewLocalRef有關本地引用的內容Android123在 Android JNI開發終極篇中將詳細講述
}

上面的代碼可能我們發現JNI中構造一個類比Java層麻煩的多,需要先擷取ID,測試是否為空白,然後編寫類方法的構造和類型簽名符號,多了很多這樣的操作,不過Android開發網提醒大家畢竟JNI中沒有類的聲明引用,只有動態擷取這些方法的ID所以執行效率可能比Java還有所降低,類似Java反射一樣的處理機制,希望大家明白這個道理。    

 四、JNI中的異常處理執行個體代碼

 class AndroidJniDemo5 {
 private native void createException() throws IllegalArgumentException; //JNI中拋出一個參數不合法異常
 private void throwException() throws NullPointerException {
  throw new NullPointerException("Java error, android123 "); //Java中產生一個null 指標異常
 }
 public static void main(String args[]) {
  AndroidJniDemo5 ajd5 = new AndroidJniDemo5();
  try {
   ajd5.createException(); 
  } catch (Exception e) {
     e.printStackTrace();
  }
 }
 static {
  System.loadLibrary("AndroidJniDemo5");
 }
}

下面的JNI中的異常具體代碼

JNIEXPORT void JNICALL
Java_AndroidJniDemo5_createException(JNIEnv *env, jobject obj)
{
 jthrowable throwable;
 jclass clazz = (*env)->GetObjectClass(env, obj);
 jmethodID mid = (*env)->GetMethodID(env, clazz, "throwException", "()V"); //擷取Java中的throwException方法ID
 if (mid == NULL)
 {
  return;
 }

 (*env)->CallVoidMethod(env, obj, mid); //執行throwException方法

 throwable = (*env)->ExceptionOccurred(env);  //有異常發生,其實Android123提醒大家還可以使用JNI中的異常檢測ExceptionCheck函數來判斷

 if (throwable)  // 如果發生了異常
 {
  jclass newExceptionClazz; 
  (*env)->ExceptionDescribe(env);
  (*env)->ExceptionClear(env);

  newExceptionClazz = (*env)->FindClass(env,"java/lang/IllegalArgumentException"); //執行個體化一個參數不合法異常

  if (newExceptionClazz == NULL)
  {
   return;
  }
  (*env)->ThrowNew(env, newExceptionClazz, "JNI cwj exception"); //在JNI中拋出異常
 }
}

 最後我們可以看到在JNI中處理很多事情確實需要編寫很多代碼,同時有關類的構造符號什麼的,目前的IDE和編譯器無法檢查,所以Android開發網提醒大家一定要記住Java簽名符號的格式和規範,下一次我們給出一些例子,協助Android NDK初學者快速瞭解JNI的規則。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.