在 Android Native 程序中输出 LOG

尽管是在 Linux Kernel 层开发,但有时还是需要接触一些 Android Native 层代码,查看相关 Log。这篇文章主要是介绍 Android 下与 Log 相关工具的用法,以及在 Native 层模块里,如何去打印 Log。

1 Liblog 库

Android 给 Native 层的程序提供一个 liblog 库,用来输出日志。如果程序中需要打印 Log,可以包含 cutils/log.h 这个头文件,并且定义自己的 LOG_TAG,就可以使用这个 liblog。liblog 提供了如下 Log 打印函数:

  • ALOGX
  • ALOGX_IF

其中 X 代表 Log 优先级,liblog 总共有5级,分别对应 V, D, I, W, E,具体意义如下:

  • V: Verbose, 调试时用的冗余信息,在 Release 版本中会被去掉,可以在程序中定义 LOG_NDEBUG 为0,来打开这个级别的 LOG
  • D: Debug, 调试 Log,在 Release 版本中会被保留,但可以动态关闭这个级别的 Log
  • I: Info,程序运行时的状态 Log,一般都会保留这个级别的 Log
  • W: Warning, 程序警告 Log,对调试非常有帮助,需要保留
  • E: Error, 程序错误 Log,这个级别 Log 优先级最高,出现这个 Log 意味着程序出错了

下面我们通过一个测试程序说明 liblog 的用法:

 
 
  1. #include <stdio.h>
  2. #include <cutils/log.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #ifdef LOG_TAG
  6. #undef LOG_TAG
  7. #endif
  8. #define LOG_TAG "mytest"
  9. static bool con = true;
  10. int main(int argc, char *argv[])
  11. {
  12. printf("this is a test log using printf");
  13. ALOGI("This is a test log using ALOGI");
  14. ALOGD("This is a test log using ALOGD");
  15. ALOGD_IF(con, "this is a test using log ALOGD_IF");
  16. return 0;
  17. }

我们需要把这个程序编译成 Android 里的可执行文件,所以还需写一个 Android.mk:

 
 
  1. LOCAL_PATH:= $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_CFLAGS += -Wall
  4. LOCAL_LDLIBS := -L$(LOCAL_PATH)/lib -llog -g
  5. LOCAL_C_INCLUDES := bionic
  6. LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
  7. LOCAL_SHARED_LIBRARIES += liblog libcutils
  8. LOCAL_SRC_FILES:= test.cpp
  9. LOCAL_MODULE := test
  10. include $(BUILD_EXECUTABLE)

把这两个文件放到 Android 源码里的一个文件夹内,然后就可以通过 mmm path/to/test 来单独编译这个程序,最后用 adb push 命令把编译的测试程序复制到手机 / Android 模拟器里,这样就可以在 adb shell 里运行我们的程序了。

2 Android Log 查看

如果直接运行,可能只能看到 printf 打印的 Log,因为使用 liblog 输出的 Log,都会放到 /dev/log/system 这个 BUFFER 里。我们可以通过 Android 自带的 logcat 工具去查看。

由于 Android 的庞大,单纯运行 logcat 命令后,我们会被各个模块打印的 Log 给淹没掉。所以得过滤没用的 Log。logcat 工具就是干这个的,使用格式如下:

 
 
  1. $ adb logcat TAG1:PRIORITY TAG2:PRIORITY

其中 TAG 就是程序中定义的 LOG_TAG,PRIORITY 就是要显示的最高 Log 级别。那么现在我们要 logcat 只显示 mytest 这个 TAG 打印的所有 Log,则可以这么写:

 
 
  1. $ adb logcat mytest:V *:S

后面跟的 *:S 就是把其他模块打印的 LOG 全部屏蔽掉。

如果需要把 printf 这样的标准打印函数也整合到 Android 日志缓存里,可以借助 logwrapper 工具。这里要注意的是所有通过 logwrapper 的日志,其 TAG 会变为程序名,而不是我们在程序里定义的 TAG。有的时候,我们需要在脚本向 Android Log 缓存中输出一些 Log,则可以借助 log 这个工具。例如:

 
 
  1. $ log -p v -t MYTEST "this is a test"

其中 -p 就是指定 Log 等级 (v, d, i, w, e)-t 是指定该 Log 的 TAG。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio ,可以使用 Android 日志系统(Logcat)来输出打印信息到控制台。 在 Native C 代码,可以使用以下方法来输出日志信息: 1. 使用 `__android_log_print` 函数 ```c #include <android/log.h> #define LOG_TAG "MyApp" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) void myFunction() { int value = 123; LOGD("The value is %d", value); } ``` 在上面的例子,`__android_log_print` 函数的第一个参数是日志级别,第二个参数是日志标签,第三个参数是日志信息(支持格式化字符串)。 日志级别常量包括: - `ANDROID_LOG_VERBOSE`: 详细信息 - `ANDROID_LOG_DEBUG`: 调试信息 - `ANDROID_LOG_INFO`: 普通信息 - `ANDROID_LOG_WARN`: 警告信息 - `ANDROID_LOG_ERROR`: 错误信息 - `ANDROID_LOG_FATAL`: 致命错误信息 2. 使用 `printf` 函数 ```c #include <stdio.h> void myFunction() { int value = 123; printf("The value is %d\n", value); } ``` 在使用 `printf` 函数时,需要注意以下事项: - 由于 Native C 代码是在本地运行的,所以需要使用本地的 `printf` 函数,而不是 Java 层的 `System.out.println` 函数。 - 输出的日志信息默认会缓存到内存,需要调用 `fflush(stdout)` 函数或者等待程序结束才能在控制台上看到输出结果。 总的来说,推荐使用 `__android_log_print` 函数来输出日志信息,可以方便地在 Android Studio 的 Logcat 查看并过滤日志信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值