Android JNI執行個體代碼(一)

來源:互聯網
上載者:User
聲明:本文轉載自android開發網,http://www.android123.com.cn/androidkaifa/683.html

  前幾天Android123有關Android JNI開發系列教程中有關的原始碼,可以在本文中尋找:

一、 在JNI中執行Java方法

class AndroidJniDemo {
 private native void executeMethod();
 private void show() {
  System.out.println("Java cwj print"); //執行了show方法後列印java層的輸出
 }
 public static void main(String args[]) {  //這裡我們在J2SE中測試,Android開發人員可以放到Activity中的onCreate調用
  AndroidJniDemo ajd = new AndroidJniDemo();
  ajd.executeMethod(); 
 }
 static {
  System.loadLibrary("AndroidJniDemo");
 }
}

下面是JNI代碼:

JNIEXPORT void JNICALL
Java_AndroidJniDemo_executeMethod(JNIEnv *env, jobject obj)
{
 jclass clazz = (*env)->GetObjectClass(env, obj); //通過類的對象
 jmethodID mid = (*env)->GetMethodID(env, clazz, "show", "()V"); //尋找java中的show方法的ID,最後的簽名符號為void類型
 if (mid == NULL) {
  return;   //如果方法ID沒有找到
 }

 printf("JNI cwj print"); //從JNI中列印輸出

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

二、擷取/設定類的域或者說屬性欄位

 (1 String類型的屬性讀寫

class AndroidJniDemo2 {
 private String sTmp;
 private native void readwriteField();
 public static void main(String args[]) {
  AndroidJniDemo2 ajd2 = new AndroidJniDemo2();
  ajd2.sTmp = "cwj";
  ajd2.readwriteField();
  System.out.println("Java cwj print ="+ajd2.sTmp);  //java層列印結果
 
 }
 static {
  System.loadLibrary("AndroidJniDemo2");
 }
}

下面是JNI層代碼:
 
JNIEXPORT void JNICALL
Java_AndroidJniDemo2_readwriteField(JNIEnv *env, jobject obj)
{
 jfieldID fid; 
 jstring jstr;
 const char *szTemp;
 
 jclass clazz = (*env)->GetObjectClass(env, obj); 
  
 fid = (*env)->GetFieldID(env, clazz, "sTmp", "Ljava/lang/String;"); // 注意sTmp是Java中聲明的,String類型在java.lang.String包中,簽名符號的格式注意
 if (fid == NULL) {
  return; 
 }
 
 jstr = (*env)->GetObjectField(env, obj, fid);  //Java的String類型,要用GetObjectField函數擷取,這裡Android123提示大家沒有GetStringField這樣的函數在JNI中,或者說在C語言中
 szTemp = (*env)->GetStringUTFChars(env, jstr, NULL); //因為還需要賦值,在C中我們轉換為utf8的類型。
 if (szTemp == NULL) {
  return; 
 }

 printf("JNI cwj print=%s", szTemp); //先列印Java層傳進來的值

 (*env)->ReleaseStringUTFChars(env, jstr, szTemp); //szTemp列印完不用了要及時釋放掉
 
 jstr = (*env)->NewStringUTF(env, "android123"); //返新的欄位值,供Java層列印
 if (jstr == NULL) {
  return;  
 }
 (*env)->SetObjectField(env, obj, fid, jstr); //設定新的屬性值。
}

  (2 int或double類似的類型的屬性讀寫,本例同時屬性值是一個靜態定義,注意下面加粗的static關鍵字

class AndroidJniDemo3 {
 private static int sAge;
 private native void readwriteField();
 public static void main(String args[]) {
  AndroidJniDemo3 ajd3 = new AndroidJniDemo3();
  AndroidJniDemo3.sAge = 23;
  ajd3.readwriteField(); //執行jni層
  System.out.println("Java cwj print="+sAge); //java層列印新的值,應該為120
 }
 static {
  System.loadLibrary("AndroidJniDemo3");
 }
}

JNIEXPORT void JNICALL
Java_AndroidJniDemo3_readwriteField(JNIEnv *env, jobject obj)
{
 jfieldID fid;
 jint nTemp;

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

 fid = (*env)->GetStaticFieldID(env, clazz, "sAge", "I"); //因為是整形,這裡簽名符號為I,注意使用的函數中包含Static代表是一個靜態屬性
 if (fid == NULL) {
  return; 
 }

 nTemp = (*env)->GetStaticIntField(env, clazz, fid);
 printf("JNI cwj print=%d", nTemp); //這裡應該顯示23
 (*env)->SetStaticIntField(env, clazz, fid, 120); //設定新的值為120,注意包含了Static,java層中定義的sAge是靜態。
}

 今天Android開發網給出了較完整的JNI下執行Java的原始碼第一部分,有關第二部分可以查看 Android 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.