在Java环境中我们使用JNI时可以使用printf函数打印,但是Android环境下使用JNI,printf函数就无效了,而我们使用IDE开发工具中的LogCat视图以及Console视图里也没有任何输出。其实,Android NDK完全支持JNI本地日志调试。为了使用日志函数,我们可以按照如下步骤实现:
1.原生代码需要先包含头文件
#include<android/log.h>
2.修改Android.mk文件,从而将原生模块与日志库进行链接,可以通过使用构建系统变量LOCAL_LDLIBS完成该操作
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS += -llog
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
3.在原生代码中配置日志消息打印
通过日志API发送给logger模块的每个日志条目都应该具有以下字段:
Priority:取值分别为verbose、debug、info、warning、error和fatal,表示信息的重要程度。
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT,
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT,
} android_LogPriority;
Tag:标识产生日志信息的组件,Logcat和DDMS工具可以基于这个标签值过滤日志信息。标签值应尽可能小。
Message:用于存放实际日志信息。
4.常用日志函数
android/log.h头文件也声明了一系列函数,这些函数主要用于原生代码生成日志消息。
_android_log_write:可用于生成一个简单的字符串作为日志信息
_android_log_write(ANDROID_LOG_WARN,"hello-jni","warning log.");
_android_log_print:可以用于生成一个格式化字符串作为日志消息。
_android_log_print(ANDROID_LOG_ERROR,"hello-jni","Failed with errno%d",erron);
_android_log_vprint:除了参数传递方式外,其他功能与_android_log_print完全相同,_android_log_vprint函数用va_list传递附加参数,而_android_log_print函数中已连续参数的方式改为传递参数。
va_list args;
va_start(args,format);
_android_log_vprint(ANDROID_LOG_VERBOSS,"hello-jni",format,args);
_android_log_assert:用于记录断言失败,它不包括日志优先级,将所有日志记录为fatal
if(0 != erron){
_android_log_assert("0!=errno","hello-jni","There is an errno");
}
案例如下:
hello-jni.c文件
#include <string.h>
#include <jni.h>
#include <android/log.h>
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
int var = 0;
var = 1;
__android_log_print(ANDROID_LOG_INFO,"HelloJni","LOVE LOG");
__android_log_print(ANDROID_LOG_DEBUG,"HelloJni","var=%d",var);
return (*env)->NewStringUTF(env, "I LOVE YOU UU! Compiled with ABI " ABI ".");
}
android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS += -llog
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
重新编译后,运行项目,我们可以看到如下日志打印: