Android Java、NDK/JNI、C++打印log


一、Java上层打印log

Android的Java程序直接调用android.util.Log类来输出Log即可。

 Log.d(TAG, "no listener for back data!");

android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。
根据首字母对应VERBOSE,DEBUG,INFO, WARN,ERROR。

1、Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思;
2、Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择
3、Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息
4、Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息
5、Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了

二、Android Studio NDK/JNI中打印log

使用<android/log.h>头文件下的 __android_log_print

2.1 示例

// 导入必须的android/log.h头文件
#include <android/log.h>

// 可选。定义方便使用的宏
#definde LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "Tag", __VA_ARGS__)

int main(int argc, char *argv[])
{
    // 直接使用LOGE宏打印
    LOGE("I'm Log!");
}

2.2 log类型

在android/log.h定义有:

typedef enum android_LogPriority {
  ANDROID_LOG_UNKNOWN = 0,
  ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
  ANDROID_LOG_VERBOSE, //logv
  ANDROID_LOG_DEBUG,   //logd
  ANDROID_LOG_INFO,    //logi
  ANDROID_LOG_WARN,    //logw
  ANDROID_LOG_ERROR,   //loge
  ANDROID_LOG_FATAL,
  ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;

三、Native层打印LOG

要在c/c++中记录Log通常的做法是:

定义自己的TAG_LOG宏;
包含头文件log.h;
然后在需要记录Log的地方直接用ALOGV/ALOGD/ALOGI/ALOGW/ALOGE即可。

比如,文件logtest.c中头文件部分这样写,

#define LOG_TAG "lights"
#include <cutils/log.h>

3.1 Liblog 库

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

ALOGX
ALOGX_IF
IF_ALOGX

ALOGX中 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 意味着程序出错了

例如:

ALOGE("%s must be defined as a build property", property);

使用ALOGx_IF() 系列函数来打印日志。ALOGx_IF() 函数根据输入的条件来决定是否打印日志,

ALOGV_IF(cond, …):cond 为 true 时输出 VERBOSE 级别的日志。
ALOGD_IF(cond, …):cond 为 true 时输出 DEBUG 级别的日志。
ALOGI_IF(cond, …):cond 为 true 时输出 INFO 级别的日志。
ALOGW_IF(cond, …):cond 为 true 时输出 WARNING 级别的日志。
ALOGE_IF(cond, …):cond 为 true 时输出 ERROR 级别的日志。

IF_ALOGx() 用于判断需求的级别是否大于当前日志级别,从而可以控制日志输出。IF_ALOGx() 系列函数包括,

IF_ALOGV():当日志级别小于等于 VERBOSE 时,返回 true。
IF_ALOGD():当日志级别小于等于 DEBUG 时,返回 true。
IF_ALOGI():当日志级别小于等于 INFO 时,返回 true。
IF_ALOGW():当日志级别小于等于 WARNING 时,返回 true。
IF_ALOGE():当日志级别小于等于 ERROR 时,返回 true。

3.2 Liblog的用法

通过一个测试程序说明 liblog 的用法:

#include <stdio.h>
#include <cutils/log.h>
#include <stdlib.h>
#include <unistd.h>
#define LOG_TAG "logtest"

static bool con = true;
int main(int argc, char *argv[])
{
    printf("this is a test log using printf");
    ALOGI("This is a test log using ALOGI");
    ALOGD("This is a test log using ALOGD");
    ALOGD_IF(con, "this is a test using log ALOGD_IF");
    return 0;
}

3.3 输出ALOGV等级的log

V等级的log如果要正常输出需要增加宏定义:

#define LOG_NDEBUG 0

设置后才可以输出ALOGV等级的log

3.4 FUNCTION与func的区别

ALOGD参数中FUNCTION与func的区别

ALOGD("%s: Value (NATIVE) = %d", __FUNCTION__, value);
ALOGD("%s: Value (NATIVE) = %d", __func__, value);

__FUNCTION__: 只输出方法名
__func__:输出方法返回值、类名、方法名

参考链接:
Android调试源码正确姿势打开ALOGV
在 Android Native 程序中输出 LOG
android系统中log机制
在 C/C++ 语言中特定的宏,如 FUNCTION

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值