小技巧:自动生成 java本地方法对应的c代码的方法名 javah 指令 +全类名

java1.6版本 class C:\workspace\HelloWorldFromC2\bin\classes
java1.7以上 src C:\workspace\HelloWorldFromC2\src

获得方法的签名的方法

javap -s 打印方法的签名 注意要cd到 C:\workspace\HelloWorldFromC2\bin\classes 传全类名

Android.mk文件的书写

Anroid.mk 文件     LOCAL_PATH := $(call my-dir)   // 返回当前c代码目录    include $(CLEAR_VARS)        // 清楚了所有 已local 开头的配置文件 唯独不清楚LOCAL_PATH    LOCAL_MODULE    := hello   // 库函数的名字 严格遵守makefile 格式 lib .so 如果前面加lib 不会自动生成了   LOCAL_SRC_FILES := Hello.c    include $(BUILD_SHARED_LIBRARY)  // 加入库函数

java调用C方法,并且传递参数

/** * 计算x和y的加法 apktools * 315 * @param x * @param y * @return */    public native int add(int x ,int y);  // char String short kiss keep it simple and stupid String[] "123:234"     /** * 给字符串后面拼装字符 加密运算 web url * @param s * @return */    public native String sayHelloInC(String s);    //     /** * 给c代码传递int数组 让c代码给这个数组进行操作 * 图形 声音的处理 * @param iNum * @return */    public native int[] intMethod(int[] iNum); 

C代码输出到控制台上LOG

#define LOG_TAG "clog"#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

传递两个int实现

JNIEXPORT jint JNICALL Java_com_example_ndkpassdata_DataProvider_add  (JNIEnv * env, jobject jobject, jint x, jint y){    // 想在logcat控制台上 打印日志    LOGD("x=%d",x);    LOGI("y=%d",y);    // log.i(TAG,"sss");    return x+y;}

字符串拼接实现

JNIEXPORT jstring JNICALL Java_com_example_ndkpassdata_DataProvider_sayHelloInC  (JNIEnv * env, jobject jobject, jstring str){    char* c="hello";    // 在C语言中不能直接操作java中的字符串    // 把java中的字符串转换成c语言中 char数组    char* cstr=Jstring2CStr(env,str);    strcat(cstr,c);    LOGD("%s",cstr);    return  (*env)->NewStringUTF(env,cstr);}

传递数组实现

JNIEXPORT jintArray JNICALL Java_com_example_ndkpassdata_DataProvider_intMethod  (JNIEnv * env, jobject jobject, jintArray jarray){    // jArray  遍历数组   jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);    // 数组的长度    jsize       (*GetArrayLength)(JNIEnv*, jarray);    // 对数组中每个元素 +5    int length=(*env)->GetArrayLength(env,jarray);    int* array=(*env)->GetIntArrayElements(env,jarray,0);    int i=0;    for(;i<length;i++){        *(array+i)+=5;    }    return jarray;}

C语言利用反射回调java方法

java的反射

Class<?> forName = Class.forName("com.example.ndkcallback.DataProvider");        Method declaredMethod = forName.getDeclaredMethod("helloFromJava", new Class[]{});        declaredMethod.invoke(forName.newInstance(), new Object[]{});

java中的方法的声明

public class DataProvider {    //C调用java空方法    public void helloFromJava(){        System.out.println("哈哈哈 我被调用了");    }    //C调用java中的带两个int参数的方法    public int Add(int x,int y){         int result=x+y;        System.out.println("result:"+result);        return result;    }    //C调用java中参数为string的方法    public void printString(String s){        System.out.println(s);    }    public static void demo(){        System.out.println("哈哈哈,我是静态方法");    }    public native void callMethod1();    public native void callMethod2();    public native void callMethod3();    public native void callMethod4();    public native void callMethod5();}

实现

实现调用java空方法

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod1  (JNIEnv * env, jobject jobject){    /*     *        Class<?> forName = Class.forName("com.example.ndkcallback.DataProvider");        Method declaredMethod = forName.getDeclaredMethod("helloFromJava", new Class[]{});        declaredMethod.invoke(forName.newInstance(), new Object[]{});     *     *     */    ///jclass      (*FindClass)(JNIEnv*, const char*);    jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");    //  jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);    // 方法签名  参数和返回值    jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V");    // void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);    (*env)->CallVoidMethod(env,jobject,methodId);}

实现调用int参数的方法

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod2  (JNIEnv *  env, jobject jobject){    jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");    jmethodID methodId=(*env)->GetMethodID(env,clazz,"Add","(II)I");    // jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);    (*env)->CallIntMethod(env,jobject,methodId,3,5);}

实现调用String参数的方法

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod3  (JNIEnv * env, jobject jobject){   // 参数 object  就是native方法所在的类    jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");        jmethodID methodId=(*env)->GetMethodID(env,clazz,"printString","(Ljava/lang/String;)V");        // jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);        jstring str=(*env)->NewStringUTF(env,"hello");        (*env)->CallVoidMethod(env,jobject,methodId,str);}

实现调用其他类中的方法,注意此时的object为该类的对象

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod4  (JNIEnv * env, jobject j){    jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/MainActivity");    //  jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);    // 方法签名  参数和返回值    jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V");    // void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);    // 需要创建DataProvider的 对象    // jobject     (*AllocObject)(JNIEnv*, jclass);    jobject obj=(*env)->AllocObject(env,clazz);  // new MainActivity();    (*env)->CallVoidMethod(env,obj,methodId);}

实现调用静态方法

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod5  (JNIEnv * env, jobject j){    jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");    //     jmethodID   (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);     jmethodID  methodid=(*env)->GetStaticMethodID(env,clazz,"demo","()V");    //void        (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);     (*env)->CallStaticVoidMethod(env,clazz,methodid);}

完成

更多相关文章

  1. Android(安卓)判断当前的界面是否是桌面的方法
  2. Android(安卓)Fragment学习之二、Fragement的使用方法
  3. android之mainfest 参数解说
  4. Android使用GPS获取用户地理位置并监听位置变化的方法
  5. Android(安卓)源码 图形系统之请求布局
  6. android 快捷键
  7. 使android dialog点击按钮dialog不消失的方法
  8. Android(安卓)NestedScrolling机制完全解析 带你玩转嵌套滑动
  9. Android(安卓)DownloadProvider分析

随机推荐

  1. php无限极分类原理
  2. php怎么分页
  3. 关于php mysqli函数的一些总结和详细介绍
  4. PHP 实现 Snowflake 生成分布式唯一 ID
  5. 关于php mysqli函数的一些总结及实例(三)
  6. 关于php mysqli函数的一些总结和实例(四)
  7. PHP基于limit子句的分页详细操作
  8. 对于PHP-FPM参数的理解
  9. 关于php mysqli函数的总结与详细介绍(二)
  10. 两步快速实现PHP分页功能,方便实用