ndk c调用java函数

静态函数调用代码

 package com.example.as;
 
 import android.os.Bundle;
 import android.app.Activity;
 import android.content.res.Resources.Theme;
 import android.view.Menu;
 import android.widget.TextView;
 
 public class MainActivity extends Activity {
 
     @Override 
     public void onCreate(Bundle savedInstanceState) 
       { 
         try {
             Thread.sleep(5000);
         } catch (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         super.onCreate(savedInstanceState); 
         TextView  tv = new TextView(this); 
         stringFromJNI();
 //        tv.setText(  ); 
         setContentView(tv); 
       } 
     public native String  stringFromJNI(); 
     public static int add(int x, int y) { 
         System.out.println("==Java静态add方法=="); 
         return x + y; 
         } 
     static { 
             System.loadLibrary("AS"); 
     }
 
 }
#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里方法是可以被重载的。"(II)I"表示的就是这个函数参数为2个int,返回值为int
其实除了自己对照手写之外,JDK也提供了一个很好用的生成签名的工具javap,cmd进入控制台到你要生成签名的那个类的class文件目录下。如我这里是MainActivity得到结果如下:

 
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
}
这就是函数和签名的对照表

非静态函数调用代码


其实很简单就是多调用一个构造函数构造出一个实例来再去调用非静态函数

package com.example.as;
 
 import android.os.Bundle;
 import android.app.Activity;
 import android.content.res.Resources.Theme;
 import android.view.Menu;
 import android.widget.TextView;
 
 public class MainActivity extends Activity {
 
     @Override 
     public void onCreate(Bundle savedInstanceState) 
       { 
         try {
             Thread.sleep(5000);
         } catch (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         super.onCreate(savedInstanceState); 
         TextView  tv = new TextView(this); 
         stringFromJNI();
 //        tv.setText(  ); 
         setContentView(tv); 
       } 
     public native String  stringFromJNI();  
     public static int add(int x, int y) { 
         System.out.println("==Java静态add方法=="); 
         return x + y; 
         } 
     static { 
             System.loadLibrary("AS"); 
     }
     
     /** C回调Java方法(非静态) */ 
     public int sub(int x, int y) { 
     System.out.println("==Java非静态sub方法=="); 
     return x - y; 
     } 
 
 }
#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;
}


 
 

你可能感兴趣的:(ndk c调用java函数)