JNI调用Java方法

在Android开发中通过AndroidStudio相关代码提示即可调用C或者C++。但在C或者C++中进行相关调用则相对复杂一些如下面简单的代码
src/main/java/top/foxhome/demo/myapplication/MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        tv = binding.sampleText;
        loadDate();
    }
    /**
     * 调用cpp方法。然后cpp再回调java方法
     */
    public native void loadDate();

    public void onDateCallBack(String date) {
        tv.setText(date);
    }

src/main/cpp/native-lib.cpp

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT void JNICALL
Java_top_foxhome_demo_myapplication_MainActivity_loadDate(JNIEnv *env, jobject thiz) {
    char *dates = "hello,word mmm";

    //    反射得到Class类型
    jclass mJclass = env->GetObjectClass(thiz);
    jmethodID methodID = env->GetMethodID(mJclass, "onDateCallBack",
                                             "(Ljava/lang/String;)V");
    jstring mData = env->NewStringUTF(dates);
    env->CallVoidMethod(thiz, methodID, mData);
}

其中调用逻辑如下:

因此我们可以得知大致流程如下:

获取jclass也可通过以下方式实现:

 jclass c = (*env)->FindClass(env,"com/xxx/xxx/类名");

获取static java方法

jmethodID methodID = env->GetStaticMethodID(mJclass, "方法名称","函数签名")

实例化对象,如实例化一个String

    jclass mStringClass = env->FindClass("java/lang/String");
    jmethodID mStringNewObjectMethod = env->GetMethodID(mStringClass, "<init>","(Ljava/lang/String;)V");
    jstring mJstring = env->NewStringUTF("hello,foxhome!");
    jobject mStringObj= env->NewObject(mStringClass,mStringNewObjectMethod,mJstring);

注意Java的函数签名可以通过Android studio的智能提示进行自动填写。也可生成class文件后执行javap -p -s XXX.class获取。

发表评论

CAPTCHAis initialing...