在前面我们讲了一下如何使用Java调用C,本文我们讲一下如何使用JNI提供的接口来反射得到Java方法进行调用。
主要步骤如下:
FindClass (找到Java层的类)
GetMethodID / GetFieldID (获取Java类中的方法 / Java类中的属性)
NewObject (创建Java对象)
Call
需要注意的是:当C调用Java的方法的时候,涉及传参的问题,需使用jni-c类型的方式进行传参。
如:
jlong total = 100;
// long total = 100; // 错误,java层获取数据存在问题
jclass clazz = env->FindClass(JNI_CLASS_PATH);
jmethodID jmethod_progress = env->GetMethodID(clazz, "****", "(J)V");
env->CallVoidMethod(obj, jmethod_progress, total);
实战
Java层:
package com.renhui.jnihelloworld;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
}
C++层:
#include
#include
#include
//FindClass (找到Java层的类)
//
//GetMethodID / GetFieldID (获取Java类中的方法 / Java类中的属性)
//
//NewObject (创建Java对象)
//
//Call
#define JNI_CLASS_PATH "com/renhui/jnihelloworld/Student"
extern "C" JNIEXPORT jstring JNICALL
Java_com_renhui_jnihelloworld_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */) {
// 找到Java层的类
jclass clazz = env->FindClass(JNI_CLASS_PATH);
jmethodID jmethod_init_id = env->GetMethodID(clazz, "
jmethodID jmethod_set_id = env->GetMethodID(clazz, "setYear", "(I)V");
jmethodID jmethod_get_id = env->GetMethodID(clazz, "getYear", "()I");
jobject obj = env->NewObject(clazz, jmethod_init_id);
env->CallVoidMethod(obj, jmethod_set_id, 28);
int year = env->CallIntMethod(obj, jmethod_get_id);
char tmp[] = {0, };
std::string hello = "Hello World, year = ";
sprintf(tmp, "%d", year);
hello.append(tmp);
return env->NewStringUTF(hello.c_str());
}
运行效果: