解读Android LOG机制的实现:c/c++域使用LOG

Android提供了的LOG机制的实现贯穿了Java,JNI,本地c/c++实现以及LINUX内核驱动等Android的各个层次,并且简单明晰,是一个相当不错的解读案例。本系列文章针对LOG机制的内部实现机理进行解读,本文是系列之六,解读Android的c/c++程序中如何使用LOG机制记录LOG信息。

 

c/c++本地库中实现LOG输出

 

通过前面的文章知道Android的Java中通过android.util.Log输出Log信息,那Android的本地c/c++程序能不能也通过这样的机制来记录Log呢?再回头看Log现有的c/c++的本地实现,答案当然是肯定的,而且是相当简单。Android直接在头文件(system/core/include/cutils/log.h)里定义了一些宏就可以很好的实现了。

 

因为,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 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)

 

而这一系列宏,最后还是用到了函数__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()。这个函数应该很熟悉吧,正是前文叙及的c/c++本地函数实现写设备文件的地方。

 

c/c++程序中记录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, etc来记录LOG。


在开发Android应用时,遇到 "fatal error: android/log.h: No such file or directory" 这个错误通常是因为编译环境缺少Android的NDK开发包,或者没有正确设置环境变量。Android NDK是Android平台上的本地开发工具包,它允许开发者使用C或C++语言来编写应用的本地部分。解决这个问题可以按照以下步骤进行: 1. 安装Android NDK: 确保你已经安装了Android NDK。如果还没有安装,可以从Android官方网站下载并安装最新版本的NDK。 2. 配置环境变量: 确保NDK的路径已经添加到系统的环境变量中。你可以在你的shell配置文件(例如`.bashrc`或`.zshrc`)中添加如下行来设置环境变量(路径根据你安装的NDK版本和位置进行相应修改): ``` export ANDROID_NDK_HOME=/path/to/your/ndk export PATH=$PATH:$ANDROID_NDK_HOME ``` 3. 在CMakeLists.txt中引入头文件: 如果你是使用CMake来构建你的项目,确保在CMakeLists.txt文件中使用`find_package(Java REQUIRED)`和`find_package(Threads REQUIRED)`等命令来确保所有的依赖项都被正确找到。此外,你还需要确保包含Android日志头文件的路径被正确指定,例如: ```cmake include_directories( ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROIDabis}/include ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROIDabis}/include/android ) ``` 4. 更新项目的gradle配置: 确保你的项目的build.gradle文件中有如下配置来指定使用NDK: ```gradle android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "" } } } externalNativeBuild { cmake { path "CMakeLists.txt" } } } ``` 5. 清理并重新构建项目: 在Android Studio中,你可以通过Build > Clean Project和Build > Rebuild Project来清理和重新构建项目,或者在命令行中使用`./gradlew clean`和`./gradlew build`命令。 按照以上步骤操作后,应该可以解决这个编译错误。如果问题依旧存在,检查NDK版本是否与项目的NDK版本要求相匹配,或者尝试重新配置NDK。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值