Android JNI (C++ )代码中的 log 输出 是由 system/core/include/cutils/log.h 控制的,里面定义了 ALOGD,ALOGI,ALOGE,ALOGW等 log 输出方式。
Log 能否在logcat 中输出 关键在于两个地方
1.宏定义 LOG_PRI
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
({ \
if (((priority == ANDROID_LOG_VERBOSE) && (LOG_NDEBUG == 0)) || \
((priority == ANDROID_LOG_DEBUG) && (LOG_NDDEBUG == 0)) || \
((priority == ANDROID_LOG_INFO) && (LOG_NIDEBUG == 0)) || \
(priority == ANDROID_LOG_WARN) || \
(priority == ANDROID_LOG_ERROR) || \
(priority == ANDROID_LOG_FATAL)) \
(void)android_printLog(priority, tag, __VA_ARGS__); \
})
#endif
从这个宏定义的角度来说,默认情况下 ALOGW,ALOGE 都是可以输出到logcat 的
对于ANDROID_LOG_DEBUG,ANDROID_LOG_VERBOSE,ANDROID_LOG_INFO
来说,如果 LOG_NDDEBUG,LOG_NIDEBUG ,LOG_NDEBUG 都会影响它们在logcat 的输出。当然这几个宏也会受到其他宏的影响,如下面的宏定义
#ifndef LOG_NDEBUG
#ifdef NDEBUG
#define LOG_NDEBUG 1
#else
#define LOG_NDEBUG 0
#endif
#endif
#ifndef LOG_NIDEBUG
#ifdef NDEBUG
#define LOG_NIDEBUG 1
#else
#define LOG_NIDEBUG 0
#endif
#endif
#ifndef LOG_NDDEBUG
#ifdef NDEBUG
#define LOG_NDDEBUG 1
#else
#define LOG_NDDEBUG 0
#endif
#endif
也就是说 宏NDEBUG 会影响这些宏,在调试代码的时候,为了保证你的ALOGD ,ALOGI,ALOGV 能够准确输出到logcat ,请在你的源代码中加入如下几行宏定义:
#undef NDEBUG
#define LOG_NIDEBUG 0
#define LOG_NDEBUG 0
#define LOG_NDDEBUG 0
2. 宏定义 android_printLog
#define android_printLog(prio, tag, fmt...) \
__android_log_print(prio, tag, fmt)
__android_log_print 在 liblog 中的 logd_write.c 中实现,最终实现的方法定义如下
static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
{
#ifdef HAVE_PTHREADS
pthread_mutex_lock(&log_init_lock);
#endif
if (write_to_log == __write_to_log_init) {
log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);
log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);
log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);
log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);
write_to_log = __write_to_log_kernel;
if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0 ||
log_fds[LOG_ID_EVENTS] < 0) {
log_close(log_fds[LOG_ID_MAIN]);
log_close(log_fds[LOG_ID_RADIO]);
log_close(log_fds[LOG_ID_EVENTS]);
log_fds[LOG_ID_MAIN] = -1;
log_fds[LOG_ID_RADIO] = -1;
log_fds[LOG_ID_EVENTS] = -1;
write_to_log = __write_to_log_null;
}
if (log_fds[LOG_ID_SYSTEM] < 0) {
log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
}
}
#ifdef HAVE_PTHREADS
pthread_mutex_unlock(&log_init_lock);
#endif
return write_to_log(log_id, vec, nr);
}
如果 write_to_log 被赋值为 __write_to_log_null,那么 log 也不会输出到 logcat