在Android C/C++层添加LOG调试(LOGI\LOGD\LOGE...)

本文介绍了解决在Android 2.3.3源代码中使用LOGD宏无法在logcat中显示输出的问题。通过在对应的mk文件中添加LOCAL_LDLIBS:=-llog,以及在cpp文件中包含特定的日志宏定义,可以实现日志信息的正确输出。同时,提供了不同级别的日志宏定义示例,并提及在编译动态库时可能遇到的问题及解决方案。

最 近在研究Android 2.3.3源代码的C/C++层,需要对代码进行一些调试,但是奇怪的是,直接添加LOGD("XXXXXXXX");,使用logcat却看不到任何输出,换成LOGI、LOGV、LOGW、LOGE也没有效果。于是在网上查找解决方法,经过几次试验,终于找到了,现在贴到下面备忘:

第一步:在对应的mk文件中加入:LOCAL_LDLIBS:= -llog
第二步:在要使用LOGcpp文件中加入:
#include <android/log.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"keymatch", __VA_ARGS__)
第三步:这样就可以使用了:LOGD("我要看到的调试信息^_^");

 

这样,在logcat端看到的输出是:

D/keymatch 32:我要看到的调试信息^_^

 

如果想改变输出中的各项内容,可以参考相应颜色的标示,比如,如果想定义LOGE,就可以把上面的ANDROID_LOG_DEBUG改成ANDROID_LOG_ERROR,同理,LOGI神马的也都以此类推:

#define LOGV(...)__android_log_print(ANDROID_LOG_VERBOSE, "ProjectName", __VA_ARGS__)
#define LOGD(...) __android_log_print(
ANDROID_LOG_DEBUG ,"ProjectName", __VA_ARGS__)
#define LOGI(...) __android_log_print(
ANDROID_LOG_INFO  ,"ProjectName", __VA_ARGS__)
#define LOGW(...) __android_log_print(
ANDROID_LOG_WARN  ,"ProjectName", __VA_ARGS__)
#define LOGE(...) __android_log_print(
ANDROID_LOG_ERROR ,"ProjectName", __VA_ARGS__)

当然,如果不嫌麻烦,也可以直接使用__android_log_print函数,而不define定义LOGxxx

 

如果还想了解更详细的内容,也可以参考这篇文章: 《在android输出log 信息 用于调试》

 

另外,有文章称此方法在编译动态库的时候可能会出问题,会提示cannot find -llog的错误。意思是找不到liblog.so这个库文件。

因此需要改成LOCAL_LDLIBS:=  -L$(SYSROOT)/usr/lib -llog才可以正常编译。但是我这边编译动态库的时候,好像不用这样改也行,没发现编译时提示“cannot find -llog”的错误。如果您在实践过程中发现有这样的问题,可以参考该文章,链接在此:《如何在android native编程中使用logCat

<think> 首先,用户的问题是关于Android开发中的头文件<android/log.h>,特别询问了其中声明的函数。用户提供了两个引用片段,我需要参考这些信息。 引用[1]是关于宏定义的:定义了LOGILOGELOGW等宏,用于在Android日志系统中打印信息。这些是基于__android_log_print函数。 引用[2]是关于JNI(Java Native Interface)的,讨论了JNIEnv和JavaVM的结构,以及JNI_OnLoad和JNI_OnUnload函数。这与日志头文件不直接相关,但可能与Android开发环境有关。 用户指定:上述引用仅供参考,并不是用户真正的需求。用户强调要参考上一次的问题和我的回答。但在对话历史中,上次用户的问题是关于快速排序的代码示例和相关问题。之前的系统级指令是关于如何格式化数学表达式和生成相关问题。 然而,当前用户的问题是独立的:"我想查询<android/log.h>头文件中声明的函数"。所以,我需要专注于回答这个问题。 我的回答必须遵守系统级指令: - 使用中文回答。 - 结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 生成相关问题。 - 对于数学表达式,使用$...$或$$...$$,但在这个上下文中可能不适用,因为这是关于C头文件的。 - LaTeX语法正确,但这里主要是代码和文本。 关键点:回答关于<android/log.h>的函数声明。 我知道<android/log.h>是Android NDK的一部分,用于本地代码(如C/C++)输出日志到Android的系统日志。主要函数包括: - __android_log_write: 写入日志消息。 - __android_log_print: 类似于printf的日志输出。 - 还有其他函数如__android_log_vprint等。 - 通常,开发者使用宏如LOGI、LOAD_ERROR等,这些在引用[1]中提到了。 用户查询"声明的函数",所以我应该列出函数声明,而不是宏。 参考标准Android文档: - 在<android/log.h>中,声明的函数包括: - int __android_log_write(int prio, const char *tag, const char *text); - int __android_log_print(int prio, const char *tag, const char *fmt, ...); - int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap); - 还有其他如__android_log_assert等。 宏如LOGV、LOGD等是基于这些函数定义的。 用户在引用中提到了__android_log_print,所以我可以基于此。 回答结构: 1. 介绍头文件:简要说明<android/log.h>的作用。 2. 列出主要声明的函数:提供函数原型。 3. 解释常用宏:因为用户提到宏,可以简要说明。 4. 添加引用标识:由于用户提供了引用,我需要自然地引用它们。 5. 生成相关问题:在最后添加相关问题部分。 引用用户给定的引用: - 引用[1]是关于宏定义的,我可以提到在<android/log.h>中定义了这些宏。 - 引用[2]是关于JNI的,可能与日志使用相关,但不是直接关于函数声明。所以,我可以忽略或不提及,除非必要。 用户说:"上述引用仅供参考",所以我应该基于可靠知识回答。 我的回答应真实可靠:我可以基于Android官方文档或常见知识。 最后,生成相关问题:例如,如何使用这些函数、日志级别等。 完整回答结构: - 开头解释头文件。 - 列出函数声明。 - 介绍宏。 - 添加引用。 - 结束with相关问题。 确保中文回答。 函数列表: 根据记忆和标准: - int __android_log_write(int priority, const char *tag, const char *text); - int __android_log_print(int priority, const char *tag, const char *format, ...); - int __android_log_vprint(int priority, const char *tag, const char *format, va_list ap); - int __android_log_assert(const char *cond, const char *tag, const char *fmt, ...); - 可能还有 __android_log_buf_print 等,但核心是这些。 优先级别如ANDROID_LOG_INFO等定义在<android/log.h>。 在回答中,我可以写成代码块。 相关问题: 1. 如何在Android NDK中使用日志功能? 2. 日志优先级有哪些级别? 3. 如何配置日志输出? 添加引用:在解释宏时可以连接到引用[1]。 例如:宏如LOGILOGE等是基于__android_log_print函数定义的,用于简化日志输出[^1]。 引用[2]似乎不相关,所以可能不提及。 最终回答: </think> ### <android/log.h> 头文件中声明的函数 `<android/log.h>` 是 Android NDK 提供的头文件,用于在本地代码(C/C++)中输出日志到 Android 系统日志(Logcat)。它声明了一系列函数和宏,方便开发者记录调试信息、错误等。以下是该头文件中声明的核心函数列表(基于 Android NDK 官方文档和常见实现),我将逐一解释其原型和用途。 #### 主要声明的函数 以下函数是 `<android/log.h>` 中直接声明的函数原型,用于处理日志输出。这些函数在本地代码(如 JNI 函数)中调用,优先级级别(如 `ANDROID_LOG_INFO`)也定义在该头文件中: - `int __android_log_write(int prio, const char *tag, const char *text);` 功能:写入一条简单的日志消息。 参数: - `prio`:日志优先级(例如 `ANDROID_LOG_INFO` 表示信息级别)。 - `tag`:日志标签(用于在 Logcat 中过滤)。 - `text`:要输出的日志文本(纯字符串)。 返回值:成功返回 0,失败返回负值。 - `int __android_log_print(int prio, const char *tag, const char *fmt, ...);` 功能:格式化输出日志消息(类似 `printf`)。 参数: - `prio`:日志优先级。 - `tag`:日志标签。 - `fmt`:格式化字符串(如 `"Error: %d"`)。 - `...`:可变参数列表(对应格式化字符串)。 返回值:成功返回 0,失败返回负值。 说明:这是最常用的函数,开发者通常通过宏(如 `LOGI`)间接调用它[^1]。 - `int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap);` 功能:格式化输出日志消息,但使用 `va_list` 参数(适用于可变参数列表的底处理)。 参数: - `prio`:日志优先级。 - `tag`:日志标签。 - `fmt`:格式化字符串。 - `ap`:`va_list` 类型的参数列表。 返回值:成功返回 0,失败返回负值。 - `int __android_log_assert(const char *cond, const char *tag, const char *fmt, ...);` 功能:输出断言失败日志(通常用于调试)。 参数: - `cond`:断言条件字符串(如 `"value != NULL"`)。 - `tag`:日志标签。 - `fmt`:格式化字符串。 - `...`:可变参数。 返回值:无返回值(如果断言失败,通常会终止程序)。 这些优先级常量也在头文件中定义,例如: - `ANDROID_LOG_UNKNOWN`(未知级别) - `ANDROID_LOG_DEFAULT`(默认级别) - `ANDROID_LOG_VERBOSE`(详细调试) - `ANDROID_LOG_DEBUG`(调试) - `ANDROID_LOG_INFO`(信息) - `ANDROID_LOG_WARN`(警告) - `ANDROID_LOG_ERROR`(错误) - `ANDROID_LOG_FATAL`(致命错误) - `ANDROID_LOG_SILENT`(静默) #### 常用宏 除了函数,`<android/log.h>` 还定义了一系列宏来简化日志输出,它们基于上述函数(如 `__android_log_print`)实现。例如: - `LOGI(...)`:用于信息级别日志(映射到 `__android_log_print(ANDROID_LOG_INFO, ...)`)。 - `LOGE(...)`:用于错误级别日志(映射到 `__android_log_print(ANDROID_LOG_ERROR, ...)`)。 - `LOGW(...)`:用于警告级别日志(映射到 `__android_log_print(ANDROID_LOG_WARN, ...)`)。 这些宏可以像这样使用:`LOGI("App started");`,输出时会自动添加标签和格式化[^1]。 #### 使用示例 在 JNI 代码中,结合 JNIEnv 接口(如引用[2]所述),您可以这样调用日志函数: ```c #include <android/log.h> #define LOG_TAG "MyApp" // 定义日志标签 void log_example(JNIEnv *env) { __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "This is a simple log message"); // 使用函数直接输出 LOGI("Formatted log: value = %d", 42); // 使用宏简化输出[^1] } ``` #### 注意事项 - **可靠性说明**:以上函数和宏是 Android NDK 的标准部分,适用于所有支持 NDK 的 Android 版本(从 API 级别 3 起)。但在使用时,需确保在 `Android.mk` 或 `CMakeLists.txt` 中链接 `liblog` 库(例如 `-llog`)。 - **引用说明**:日志宏如 `LOGI` 和 `LOGE` 是基于 `__android_log_print` 函数实现的,这简化了开发者的日志输出过程[^1]。此外,在 JNI 环境中,日志函数常配合 `JNIEnv` 结构体使用,但 `<android/log.h>` 本身独立于 JNI[^2]。 如果您需要完整的头文件内容,建议查看 Android NDK 源代码中的 `<android/log.h>` 文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值