zoukankan      html  css  js  c++  java
  • 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方法签名:

      

    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

     
  • 相关阅读:
    UpdateBatch到底是怎么用的?
    进度条在.net导入Excel时的应用实例
    asp.net页面触发事件panel滚动条高度不变的实现方法
    .NET中的枚举用法浅析
    .NET程序调试技巧(一):快速定位异常的一些方法
    ASP.NET实现推送文件到浏览器的方法
    微软官方SqlHelper类 数据库辅助操作类
    Asp.net中使用文本框的值动态生成控件的方法
    ASP.NET中Dictionary基本用法实例分析
    ASP.NET动态增加HTML元素的方法实例小结
  • 原文地址:https://www.cnblogs.com/lbangel/p/3762864.html
Copyright © 2011-2022 走看看