JNI学习(一)(c和java层对象互相调用)

c层调用java对象

package com.example.bean;

/**
 *
 * java对象
 * @author telenewbie
 *
 */
public class JNI_cCalljava_test {

    public static int num = 0;

    private String name;

    public static int intMethod(int n) {
        num = n * n;
        return num;
    }

    public static boolean booleanMethod(boolean bool) {
        return !bool;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }


}
#include <com_example_test_TestJava.h>
#include <jni.h>
#include <stdio.h>

#ifdef ANDROID
#include <jni.h>
#include <android/log.h>
#define LOGE(format, ...)  __android_log_print(ANDROID_LOG_ERROR, "(>_<)", format, ##__VA_ARGS__)
#define LOGI(format, ...)  __android_log_print(ANDROID_LOG_INFO,  "(^_^)", format, ##__VA_ARGS__)
#else
#define LOGE(format, ...)  printf("(>_<) " format "\n", ##__VA_ARGS__)
#define LOGI(format, ...)  printf("(^_^) " format "\n", ##__VA_ARGS__)
#endif

//直接为java对象进行赋值
void test(JNIEnv * env, jobject object) {
    jint square;
    //在c代码里面调用java代码里面的方法
    // java 反射
    //1 . 找到java代码的 class文件
    //    jclass      (*FindClass)(JNIEnv*, const char*);
    jclass dpclazz = (*env)->FindClass(env,
            "com/example/bean/JNI_cCalljava_test");
    if (dpclazz == 0) {
        LOGI("find class error");
        return;
    }
    LOGI("find class ");

    //2 寻找class里面的方法,(此处为静态方法)
    //   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID method1 = (*env)->GetStaticMethodID(env, dpclazz, "intMethod",
            "(I)I");
    if (method1 == 0) {
        LOGI("find method1 error");
        return;
    }
    LOGI("find method1 ");
    //3 .调用这个方法(因为调用的是静态方法传递类名即可,如果是对象,则需要更改方式)
    //    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    square = (*env)->CallStaticIntMethod(env, dpclazz, method1, 5);
    LOGI("output %d",square);
}

JNIEXPORT jstring JNICALL Java_com_example_test_TestJava_speak(JNIEnv * env,
        jobject object) {
    LOGI("dufresne Hello World From libhelloworld.so!");
    test(env, object);
    return (*env)->NewStringUTF(env, "Hello World! I am Native interface");
}

//使用反射为对象赋值,返回java层的对象
JNIEXPORT jobject JNICALL Java_com_example_test_TestJava_getMyClass(
        JNIEnv * env, jobject obj, jint age, jstring name) {
    jclass cls = (*env)->FindClass(env, "com/example/bean/MyClass");
    if (cls == 0) {
        LOGE("find MyClass Error");
        return NULL;
    }
    jobject dpobj = (*env)->AllocObject(env, cls);

    LOGI("obj=%d,dpobj=%d",obj,dpobj);

    jmethodID method1 = (*env)->GetMethodID(env, cls, "setName",
            "(Ljava/lang/String;)V");
    if (method1 != 0) {
        (*env)->CallVoidMethod(env, dpobj, method1, name);
    } else {
        LOGE("cant find setName method");
    }
    jmethodID method2 = (*env)->GetMethodID(env, cls, "setAge", "(I)V");
    if (method2 != 0) {
        (*env)->CallVoidMethod(env, dpobj, method2, age);
    } else {
        LOGE("can't find method setAge");
    }

    return dpobj;
}

/* This function will be call when the library first be load.
 * You can do some init in the libray. return which version jni it support.
 */
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    LOGI("dufresne----->JNI_OnLoad!");
    return JNI_VERSION_1_4;
}
package com.example.test;

public class TestJava {

//如果是静态方法的话,传递给jni层的jobject为jclass对象,否则就是对象
    public static native String speak();

    public static native Object getMyClass(int age, String name);

    static {
        System.loadLibrary("HelloWorldJni");
    }

}

android.mk

LOCAL_PATH:= $(call my-dir)
# 一个完整模块编译
include $(CLEAR_VARS)
LOCAL_LDLIBS    := -lm -llog 
LOCAL_SRC_FILES:=Hello.c
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_MODULE := libHelloWorldJni
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS :=optional
include $(BUILD_SHARED_LIBRARY)

猜你喜欢

转载自blog.csdn.net/telenewbie/article/details/78211659
今日推荐