zoukankan      html  css  js  c++  java
  • 在Android的c/c++代码中使用LOG

    在Android中,Java代码通过android.util.Log输出Log信息,同样的本地c/c++代码也提供了相对应而且是更多的接口。Android直接在头文件(system/core/include/cutils/log.h)里定义了一些日志输出的宏,这些宏比android.util.Log提供了更多的日志输出接口。因此,使用这些宏,就可以进行和java代码中一样的日志输出。宏LOGD(),LOGE(),LOGI(),LOGV(),LOGW(),LOGD()分别对应android.util.Log中的Log.d(),Log.e(),Log.i(),Log.v(),Log.w()。

    注意:这里的都是把日志输出到Main缓冲区。
    另外,关于此文最好对照着《Android LOG机制流程图》一起来看。
    log.h中对日志输出还提供一些更细的宏,比如对于LOGD(),还提供了LOGD_IF(),IF_LOGD(),SLOGD(),SLOGD_IF()。其中LOGD_IF()表示条件输出,IF_LOGD()用于测试是否需要输出,SLOGD()表示把日志输出到System日志缓冲,SLOGD_IF()表示条件成立的情况下,把日志输出到System日志缓冲。
    注意:IF_LOGD()现在总是返回1.
    因为,LOG分了VERBOSE/DEBUG/INFO/WARN/ERROR/ASSERT等类别,简单起见,以DEBUG为例的实现来说明。
    #ifndef LOGD
    #define LOGD(...) LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
    #endif
     
    #ifndef LOGD_IF
    #define LOGD_IF(cond, ...) 
        ( (CONDITION(cond))
        ? LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
        : (void)0 )
    #endif
     
    #ifndef IF_LOGD
     #define IF_LOGD() IF_LOG(LOG_DEBUG, LOG_TAG)
    #endif
     
    #ifndef SLOGD
     #define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
    #endif
    #ifndef SLOGD_IF
     #define SLOGD_IF(cond, ...)
         ( (CONDITION(cond))
         ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
         : (void)0 )
     #endif
     宏LOGD(),LOGE(),LOGI(),LOGV(),LOGW(),LOGD()其实最好后会使用以下的宏。
    #ifndef LOG
    #define LOG(priority, tag, ...)
        LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
    #endif
    #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
     
    #define android_printLog(prio, tag, fmt...)
    __android_log_print(prio, tag, fmt)
    而这一系列宏,最后还是调用了system/core/liblog/logd_write.c中的__android_log_print()
    int __android_log_print(int prio, const char *tag, const char *fmt, ...)
    {
        va_list ap;
        char buf[LOG_BUF_SIZE];
     
        va_start(ap, fmt);
        vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
        va_end(ap);
     
        return __android_log_write(prio, tag, buf);
    }
    这里还是调到了函数__android_log_write()。__android_log_write()组织了参数,又调用了write_to_log这个函数指针。
    关于write_to_log这个函数指针的调用详情请参考《Android中LOG机制详解
     
    要在c/c++中使用Log,很简单。通常的做法是:
    定义自己的TAG_LOG宏;包含头文件log.h;然后在需要记录Log的地方直接用LOGV/LOGD/LOGI/LOGW/LOGE等即可。
    比如,文件lights.c中就在开头这样写,
    #define LOG_TAG "lights"
    #include <cutils/log.h> 
    然后在该文件的后续部分,直接用LOGV/LOGE等来输出日志就可以。
  • 相关阅读:
    mysql常用命令
    怎么在cmd中输入mysql就可以进去mysql控制台
    ORA-01659: 无法分配超出 7 的 MINEXTENTS
    Oracle修改表空间自增长
    整理下.net分布式系统架构的思路
    Net分布式系统之一:系统整体框架介绍
    QT QTreeWidget 的一个例子 显示文件(夹)的树形结构
    待读 QT 博客
    如何为 QT5 装上 QT4 才有的库
    Python 获取文件夹里所有 log 的起止时间戳
  • 原文地址:https://www.cnblogs.com/liyuzhao/p/3818209.html
Copyright © 2011-2022 走看看