Android4.1 JNI 中打印的LOG 无法在 logcat 中输出

本文详细解析了Android JNI中C++代码的日志输出控制,关键在于`LOG_PRI`宏定义和`android_printLog`的实现。在调试时,通过调整`NDEBUG`及相关宏可确保ALOGD、ALOGI、ALOGV等输出到logcat。同时,`logd_write.c`中的`__write_to_log_init`决定了日志是否真正写入到设备文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


   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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值