六、Android学习笔记_JNI_c调用java代码

1、编写native方法(java2c)和非native方法(c2java):

package com.example.provider;



public class CallbackJava {



    // C调用java空方法

    public void helloFromJava() {



        System.out.println("hello from java");

    }



    // C调用java中的带两个int参数的方法

    public int Add(int x, int y) {

        int result = x + y;

        System.out.println("java result=" + result);

        return result;

    }



    // C调用java中参数为string的方法

    public void printString(String s) {

        System.out.println("java " + s);

    }



    //静态方法

    public static void printStaticStr(String s) {

        System.out.println("java static-> " + s);

    }



    // 让c代码调用对应的java代码

    public native void callHelloFromJava();



    public native void callAdd();



    public native void callPrintString();



    // 调用一个静态的c代码

    public native void callPrintStaticStr();

}
 

2、通过javah命令生成签名,通过javap命令生产native方法签名:

  六、Android学习笔记_JNI_c调用java代码

3、c代码

FindClass:找到java中的类文件
GetMethodID:根据类和方法签名找到要调用的方法。

#include <stdio.h>

#include <jni.h>

#include <malloc.h>

#include "com_example_provider_CallbackJava.h";

#include "com_example_jni_MainActivity.h";



#include <android/log.h>

#define LOG_TAG "System.out.c"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)



jmethodID getMethodId(JNIEnv * env, char* methodname, char* signname) {

    jclass jclazz = (*env)->FindClass(env, "com/example/provider/CallbackJava");

    if (jclazz == 0) {

        LOGD("class not find ");

        return;

    }

    //2、找class中方法的id,第三个参数方法名称,第四个参数该方法对应的签名

    jmethodID methodid = (*env)->GetMethodID(env, jclazz, methodname, signname);

    if (methodid == 0) {

        LOGD("method not find ");

        return;

    }

    return methodid;

}



JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callHelloFromJava

(JNIEnv * env, jobject obj) {

    //1、 找java中的class文件

    //第二个参数是类名的(包名)

    jclass jclazz = (*env)->FindClass(env,"com/example/provider/CallbackJava");

    if(jclazz==0) {

        LOGD("class not find ");

        return;

    }

    //2、找class中方法的id,第三个参数方法名称,第四个参数该方法对应的签名

    jmethodID methodid = (*env)->GetMethodID(env, jclazz,"helloFromJava","()V");

    if(methodid==0) {

        LOGD("helloFromJava method not find ");

        return;

    }

    //3、调用方法

    //void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);

    (*env)->CallVoidMethod(env,obj,methodid);

}



JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callAdd

(JNIEnv *env, jobject obj) {

    jmethodID mid = getMethodId(env,"Add","(II)I");

    int result = (*env)->CallIntMethod(env, obj, mid,3,6);

    LOGD("c to java add: d%",result);

}



JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callPrintString

(JNIEnv *env, jobject obj) {

    LOGD("c to java callPrintString start ");

    jmethodID mid = getMethodId(env,"printString","(Ljava/lang/String;)V");

    (*env)->CallVoidMethod(env, obj, mid,(*env)->NewStringUTF(env," call printString finish"));

    LOGD("c to java callPrintString finish ");

}



JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callPrintStaticStr

(JNIEnv *env, jobject obj) {

    jclass jclazz = (*env)->FindClass(env, "com/example/provider/CallbackJava");

    if (jclazz == 0) {

        LOGD("class not find ");

        return;

    }

    //静态方法调用GetStaticMethodID 和 CallStaticXXXMethod

    jmethodID methodid = (*env)->GetStaticMethodID(env, jclazz, "printStaticStr", "(Ljava/lang/String;)V");

    if (methodid == 0) {

        LOGD("printStaticStr method not find ");

        return;

    }

    (*env)->CallStaticVoidMethod(env, jclazz, methodid,(*env)->NewStringUTF(env,"static hello java"));



}



JNIEXPORT void JNICALL Java_com_example_jni_MainActivity_callProvider

  (JNIEnv *env, jobject obj){

    jclass jclazz = (*env)->FindClass(env,"com/example/provider/CallbackJava");

    if(jclazz==0) {

        LOGD("class not find ");

        return;

    }

    jmethodID methodid = (*env)->GetMethodID(env, jclazz,"helloFromJava","()V");

    if(methodid==0) {

        LOGD("helloFromJava method not find ");

        return;

    }

    //创建一个CallbackJava对象

    jobject jobj =(*env)->AllocObject(env, jclazz);

    (*env)->CallVoidMethod(env,jobj,methodid);



}
 

    4、编译多个c文件可以用空格分开

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    :=Hello

#LOCAL_SRC_FILES :=Hello.c

LOCAL_SRC_FILES :=CallbackJava.c Hello.c

LOCAL_LDLIBS += -llog

include $(BUILD_SHARED_LIBRARY)

 

参考http://www.open-open.com/lib/view/open1359700820369.html

你可能感兴趣的:(Android学习)