在jni的c、c++文件输出本地log首先要引入ndk的log.h头文件,文件在ndk目录的 \android-ndk-r13b-windows-x86_64\android-ndk-r13b\platforms\android-24\arch-x86\usr\include\android中。
打开头文件可以看到定义了一个枚举的log优先级和具体打印log的方法
/*
* Android log priority values, in ascending priority order.
*/
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
/*
* 输出一个简单字符串log 参数:log优先级, log标志,log内容
*/
int __android_log_write(int prio, const char *tag, const char *text);
/*
* 输出一个格式字符串的log,用法同printf
*/
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 3, 4)))
#endif
;
/*
* A variant of __android_log_print() that takes a va_list to list
* additional parameters.
*/
int __android_log_vprint(int prio, const char *tag,
const char *fmt, va_list ap);
/*
* Log an assertion failure and SIGTRAP the process to have a chance
* to inspect it, if a debugger is attached. This uses the FATAL priority.
*/
void __android_log_assert(const char *cond, const char *tag,
const char *fmt, ...)
a、引入log.h头文件
#include <android/log.h>
b、调用方法输出log
__android_log_print(ANDROID_LOG_DEBUG, “MyLog“, "Hello jni , test log....");
通过定义宏减少重复代码的使用,如下代码:
#include <jni.h>
#include <string>
#include <android/log.h>
// Log标记
#define LOG_TAG "MyLog"
// 各个优先级的宏定义
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_write(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL
Java_com_aidesudi_testjni_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
// 直接调试方式输出
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Hello jni , test log....");
// 通过定义宏输出
LOGV("Print the log V ");
LOGE("Print the log ERROR : %s",hello.c_str());
LOGI("Print the log INFO : %d", 12345);
LOGW("Pring the log WARN ");
LOGD("Pring the log DEBUG :%s","Test print log");
return env->NewStringUTF(hello.c_str());
}
#ifdef __cplusplus
}
#endif
运行代码可以在控制看到如下log信息,大大方便jni代码的调试;
当然也可以将上面定义的宏放在一个头文件中,做为一个公用的头文件可以在不同项目或多个c/c++文件中使用,比如:mylog.h
#ifndef TESTJNI_MYLOG_H
#define TESTJNI_MYLOG_H
#include <android/log.h>
// Log标记
#define LOG_TAG "MyLog"
// 各个优先级的宏定义
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_write(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#endif //TESTJNI_MYLOG_H
使用的时候直接引入 mylog.h 头文件,#include "mylog.h" 然后直接调用具体优先级log输出方法即可。