ndk c調用java函數

靜態函數調用代碼

 1 package com.example.as;
 2 
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.content.res.Resources.Theme;
 6 import android.view.Menu;
 7 import android.widget.TextView;
 8 
 9 public class MainActivity extends Activity {
10 
11     @Override 
12     public void onCreate(Bundle savedInstanceState) 
13       { 
14         try {
15             Thread.sleep(5000);
16         } catch (InterruptedException e) {
17             // TODO Auto-generated catch block
18             e.printStackTrace();
19         }
20         super.onCreate(savedInstanceState); 
21         TextView  tv = new TextView(this); 
22         stringFromJNI();
23 //        tv.setText(  ); 
24         setContentView(tv); 
25       } 
26     public native String  stringFromJNI(); 
27     public native String  unimplementedStringFromJNI(); 
28     public static int add(int x, int y) { 
29         System.out.println("==Java靜態add方法=="); 
30         return x + y; 
31         } 
32     static { 
33             System.loadLibrary("AS"); 
34     }
35 
36 }
#include <jni.h>
#include <string.h>
#include <stdio.h>

int Java_com_example_as_MainActivity_stringFromJNI(JNIEnv* env,
        jobject thiz) {

    // 獲取類
    jclass AnalyzeCidUtil = (*env)->FindClass(env,"com/example/as/MainActivity");
    if (NULL == AnalyzeCidUtil) {
        return -1;
    }

    // 獲取類add靜態方法
    jmethodID add = (*env)->GetStaticMethodID(env,AnalyzeCidUtil, "add", "(II)I");
    if (NULL == add) {
        (*env)->DeleteLocalRef(env,AnalyzeCidUtil); // 刪除類指引
        return -2;
    }

    // 調用靜態int方法
    int result = (*env)->CallStaticIntMethod(env,AnalyzeCidUtil, add, 3, 5);

    return 0;
}

代碼解釋

java中定義了一個靜態函數publicstaticintadd(intx,inty) ,在C中經過FindClass找到類,GetStaticMethodID找到方法,經過CallStaticIntMethod調用方法
GetStaticMethodID的第4個參數是什麼意思呢? "(II)I"
這個是方法簽名

方法簽名

 

在這裏有必要單獨來說一講這個方法簽名,爲何要用這個東東呢?咱們知道,在Java裏方法是能夠被重載的,好比我一個類裏有public>"(II)I"表示的就是這個函數參數爲2個int,返回值爲int
其實除了本身對照手寫以外,JDK也提供了一個很好用的生成簽名的工具javap,cmd進入控制檯到你要生成簽名的那個類的class文件目錄下。如我這裏是MainActivity獲得結果以下:java

 
E:\Users\fish\workspace\AS\bin\classes\com\example\as>javap -s MainActivity
Compiled from "MainActivity.java"
public class com.example.as.MainActivity extends android.app.Activity{
static {};
  Signature: ()V
public com.example.as.MainActivity();
  Signature: ()V
public void onCreate(android.os.Bundle);
  Signature: (Landroid/os/Bundle;)V
public native java.lang.String stringFromJNI(java.lang.String);
  Signature: (Ljava/lang/String;)Ljava/lang/String;
public native java.lang.String unimplementedStringFromJNI();
  Signature: ()Ljava/lang/String;
public static int add(int, int);
  Signature: (II)I
}
這就是函數和簽名的對照表

非靜態函數調用代碼

其實很簡單就是多調用一個構造函數構造出一個實例來再去調用非靜態函數android

 1 package com.example.as;
 2 
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.content.res.Resources.Theme;
 6 import android.view.Menu;
 7 import android.widget.TextView;
 8 
 9 public class MainActivity extends Activity {
10 
11     @Override 
12     public void onCreate(Bundle savedInstanceState) 
13       { 
14         try {
15             Thread.sleep(5000);
16         } catch (InterruptedException e) {
17             // TODO Auto-generated catch block
18             e.printStackTrace();
19         }
20         super.onCreate(savedInstanceState); 
21         TextView  tv = new TextView(this); 
22         stringFromJNI();
23 //        tv.setText(  ); 
24         setContentView(tv); 
25       } 
26     public native String  stringFromJNI(); 
27     public native String  unimplementedStringFromJNI(); 
28     public static int add(int x, int y) { 
29         System.out.println("==Java靜態add方法=="); 
30         return x + y; 
31         } 
32     static { 
33             System.loadLibrary("AS"); 
34     }
35     
36     /** C回調Java方法(非靜態) */ 
37     public int sub(int x, int y) { 
38     System.out.println("==Java非靜態sub方法=="); 
39     return x - y; 
40     } 
41 
42 }
#include <jni.h>
#include <string.h>
#include <stdio.h>
/**
 * 實例化類對象
 */
jobject getInstance(JNIEnv *env, jclass clazz) {
    // 獲取構造方法
    jmethodID constructor = (*env)->GetMethodID(env,clazz, "<init>", "()V");
    if (NULL == constructor) {
        return NULL;
    }
    // 實例化類對象
    return (*env)->NewObject(env,clazz, constructor);
}
int Java_com_example_as_MainActivity_stringFromJNI(JNIEnv* env,
        jobject thiz) {

        // 獲取類
        jclass  AnalyzeCidUtil = (*env)->FindClass(env,"com/example/as/MainActivity");
        if (NULL == AnalyzeCidUtil) {
            return -1;
        }

        // 實例化類對象
        jobject mAnalyzeCidUtil = getInstance(env, AnalyzeCidUtil);
        if (NULL == mAnalyzeCidUtil) {
            (*env)->DeleteLocalRef(env,AnalyzeCidUtil); // 刪除類指引
            return -2;
        }

        // 獲取對象sub方法
        jmethodID sub = (*env)->GetMethodID(env,AnalyzeCidUtil, "sub", "(II)I");
        if (NULL == sub) {
            (*env)->DeleteLocalRef(env,AnalyzeCidUtil); // 刪除類指引
            (*env)->DeleteLocalRef(env,mAnalyzeCidUtil); // 刪除類對象指引
            return -3;
        }

        // 調用非靜態int方法
        int result = (*env)->CallIntMethod(env,mAnalyzeCidUtil, sub, 6, 76);
        

    return 0;
}
相關文章
相關標籤/搜索