JNI实战(四):C 调用 Java

在前面我们讲了一下如何使用Java调用C,本文我们讲一下如何使用JNI提供的接口来反射得到Java方法进行调用。

主要步骤如下:

  1. FindClass (找到Java层的类)
  2.  GetMethodID /  GetFieldID (获取Java类中的方法 / Java类中的属性)
  3.  NewObject (创建Java对象)
  4.  Call<TYPE> Method / [G/S]et<Type> Field (调用方法 / 设置属性)

需要注意的是:当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 <jni.h>
#include <string>
#include <iostream>

//FindClass (找到Java层的类)
//
//GetMethodID /  GetFieldID (获取Java类中的方法 / Java类中的属性)
//
//NewObject (创建Java对象)
//
//Call<TYPE> Method / [G/S]et<Type> Field (调用方法 / 设置属性)

#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, "<init>", "()V");
    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());
}

运行效果:

 

  

posted @ 2019-03-08 16:28  灰色飘零  阅读(1398)  评论(0编辑  收藏  举报