安卓篱笆

标题: Android安卓JNI/NDK开发(二) [打印本页]

作者: GuiTarvvm2098    时间: 2017-11-30 04:12
标题: Android安卓JNI/NDK开发(二)
[attach]411[/attach]

上一篇讲了jni的创建,这一篇讲java和c之间的调用。如有地方觉得突如其来可以看上一篇的内容后再看这篇。

一、java调用c语言

有时jni的native方法多的时候我们在一个个去写c方法就很烦人,此时我们可以自动生成相应的c方法。

1、我们先写好本地native方法

2、然后生成c的头文件,两种方式。

1.在\NDKDemo\app\src\main\java

执行命令:javah com.atguigu.ndkdemo.native方法所在类的全类名

命令行可以用studio的,也可以用cmd 的

2.另外一种是在项目的build/intermaediates/classes/debug/下执行

命令 : javah -classpath . -jni native方法所在类的全类名

3、把头文件移到jni目录下

4、创建一个c的源文件,然后#include "com_example_javacallc_MyJni.h"

5、然后把头文件中的方法复制过来,然后就可以写方法体了。

这里我们就用了快捷的方式生成了头文件而已,其余的和一里面一样操作。

二、c调java

我们的做法是先用java调c,让c来响应,然后在c里面写上调java的代码来实现c调java

1、java调c这和上面一样,就不赘述

2、c调java就分四步;

1. 用反射得到jclass对象:参数2是类的全名,用反斜杠代替点,因为在linux下反斜杠才代表下级路径

jclass clazz = (*env)->FindClass(env,"com/example/ccalljava/Myjni");

2. 得到对应方法的Method对象 : 参数2是类,参数3是方法名,就是要被调的java方法名,参数4是方法签名,方法签名下面有讲到。

jmethodID method = (*env)->GetMethodID(env,clazz,"add","()V");

------------方法签名start------------

在头文件中,每个方法的文档注释部分Signature就是方法签名

/*

* Signature: (Ljava/lang/String;)Ljava/lang/String ;

*/

从括号开始一个都不要漏,包括最后的分号都属于签名,画线加粗部分

如果头文件中没有可以自己手动查看

1). 在命令行窗口中, 进入classes/debug/目录

2). 执行命令: javap -s 全类名, 就会显示所有方法的签名信息

-----------方法签名end--------------

3. 创建类对象,如果是调用的静态java方法这一步就不用。

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

4. 调用方法,根据返回值类型来调不同的方法

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

/**调用静态方法时就不要步骤3,步骤2变成getStaticMethodID,步骤4变成CallStaticXXXMethod。**/

三、在c中打log

-------------AS中使用-------------

1. 在build.gradle中ndk配置中添加配置:ldLibs "log"

defaultConfig {

applicationId "com.atguigu.javacallc"

minSdkVersion 14

targetSdkVersion 23

versionCode 1

versionName "1.0"

ndk{

moduleName "javaCallC" //so文件: lib+moduleName+.so

abiFilters "armeabi", "armeabi-v7a", "x86" //cpu的类型

ldLibs "log"

}

}

2. 包含日志头文件, 定义日志输出函数

#include <android/log.h>

#define LOG_TAG "yzy"

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

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

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

3. 调用日志输出函数

LOGE("内容");

---------Eclipse中使用---------------

1. 在Android.mk中添加配置

LOCAL_LDLIBS += -llog

2. 在C文件中引入定义:

#include <android/log.h>

#define LOG_TAG "atguigu"

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

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

3. 调用

LOGE("result=%d \n", result);

如果有误欢迎评论指出。。




欢迎光临 安卓篱笆 (http://www.okapk.cn/) Powered by Discuz! X3.2