zoukankan      html  css  js  c++  java
  • Android C代码回调java方法

    本文将讲述下列三种C代码回调java方法

    1、c代码回调java空方法

    2、c代码回调java int类型参数方法

    3、c代码回调javaString类型参数方法

    方法都差不多,先看c代码回调java空方法,其他两种类似:

    ① 找到字节码对象 

    //jclass (*FindClass)(JNIEnv*, const char*);

    //第二个参数 要回调的java方法所在的类的路径 "com/itheima/callbackjava/JNI"

    ② 通过字节码对象找到方法对象

    //jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

    第二个参数 字节码对象 第三个参数 要反射调用的java方法名 第四个参数 要反射调用的java方法签名

    javap -s 要获取方法签名的类的全类名 项目/bin/classes 运行javap

    ③ 通过字节码创建 java对象(可选) 如果本地方法和要回调的java方法在同一个类里可以直接用 jni传过来的java对象 调用创建的Method

    jobject obj =(*env)->AllocObject(env,claz);

    当回调的方法跟本地方法不在一个类里 需要通过刚创建的字节码对象手动创建一个java对象

    再通过这个对象来回调java的方法

    需要注意的是 如果创建的是一个activity对象 回调的方法还包含上下文 这个方法行不通!!!回报空指针异常

    ④ 反射调用java方法

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

    第二个参数 调用java方法的对象 第三个参数 要调用的jmethodID对象 可选的参数 调用方法时接收的参数

    接下来实战项目实现

    新建项目,布局如下:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity" >
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="callbackvoid"
            android:text="回调null方法" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="callbackint"
            android:text="回调int参数方法" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="callbackString"
            android:text="回调String参数方法" />
    
    </LinearLayout>

    新建JNI.java

    package com.wuyudong.callbackjava;
    
    public class JNI {
        
        static{
            System.loadLibrary("callback");
        }
    
        public native void callbackvoidmethod();
        
        public native void callbackintmethod();
        
        public native void callbackStringmethod();
    
        // C调用java空方法
        public void helloFromJava() {
            System.out.println("hello from java");
    
        }
    
        // C调用Java中的带两个int参数的方法
        public int add(int x, int y) {
            return x + y;
        }
    
        // C调用java中参数为String的方法
        public void printString(String s) {
            System.out.println(s);
    
        }
    }

    MainActivity.java

    package com.wuyudong.callbackjava;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.view.Menu;
    import android.view.View;
    
    public class MainActivity extends Activity {
        
        JNI jni;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            jni = new JNI();
        }
    
        public void callbackvoid(View v) {
            jni.callbackvoidmethod();
        }
        
        
        public void callbackint(View v) {
            jni.callbackintmethod();
        }
        
        public void callbackString(View v) {
            jni.callbackStringmethod();
        }
    }

    callback.c

    #include <jni.h>
    #include <android/log.h>
    #define LOG_TAG "System.out"
    #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
    
    JNIEXPORT void JNICALL Java_com_wuyudong_callbackjava_JNI_callbackvoidmethod(
            JNIEnv * env, jobject clazz) {
        //1、获取字节码对象 jclass (*FindClass)(JNIEnv*, const char*);
        jclass claz = (*env)->FindClass(env, "com/wuyudong/callbackjava/JNI");
    
        //2、获取Method对象 jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
        jmethodID methodID = (*env)->GetMethodID(env, claz, "helloFromJava", "()V");
    
        //3、通过字节码对象创建一个Object(即是clazz)
        //4、通过对象调用方法
        (*env)->CallVoidMethod(env, clazz, methodID);
    
    }
    
    JNIEXPORT void JNICALL Java_com_wuyudong_callbackjava_JNI_callbackintmethod(
            JNIEnv * env, jobject clazz) {
        //1、获取字节码对象 jclass (*FindClass)(JNIEnv*, const char*);
        jclass claz = (*env)->FindClass(env, "com/wuyudong/callbackjava/JNI");
    
        //2、获取Method对象 jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
        jmethodID methodID = (*env)->GetMethodID(env, claz, "add", "(II)I");
    
        //3、通过字节码对象创建一个Object(即是clazz)
        //4、通过对象调用方法
        int result = (*env)->CallIntMethod(env, clazz, methodID, 3, 5);
        LOGD("result = %d", result);
    
    }
    
    JNIEXPORT void JNICALL Java_com_wuyudong_callbackjava_JNI_callbackStringmethod(
            JNIEnv * env, jobject clazz) {
        //1、获取字节码对象 jclass (*FindClass)(JNIEnv*, const char*);
        jclass claz = (*env)->FindClass(env, "com/wuyudong/callbackjava/JNI");
    
        //2、获取Method对象 jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
        jmethodID methodID = (*env)->GetMethodID(env, claz, "printString",
                "(Ljava/lang/String;)V");
    
        //3、通过字节码对象创建一个Object(即是clazz)
        //4、通过对象调用方法
        //char* str = "hello from c!";
        jstring result = (*env)->NewStringUTF(env, "hello from c");
        (*env)->CallVoidMethod(env, clazz, methodID, result);
    
    }

    获取更多C语言与算法相关知识,关注公众号:“csuanfa”

  • 相关阅读:
    BEA WebLogic JRockit的使用和性能调优
    项目调优笔记
    设计资源收集
    2011年推荐WEB在线应用
    Oracle10g调优:Oracle10g AWR使用方法及分析
    谈数据库的性能优化
    EXTJS双击关闭标签代码
    chrome插件API协议(Extensions Context Menu API Proposal)
    ASH Report For AWDDB/awddb
    java内存查看与分析
  • 原文地址:https://www.cnblogs.com/wuyudong/p/5635508.html
Copyright © 2011-2022 走看看