Android中Log.d和Log.v如何实现在release版本不输出

本文探讨了Android系统如何在Release版本中不输出Log.d和Log.v。在native code中,通过编译宏开关参数实现;在Java代码中,利用Config.LOGV变量在Android.mk中控制。当Config.LOGV为真时,才会执行Log输出。Android 2.2后的Slog.java类也遵循相同机制,但每次写Log需添加条件判断,增加了代码复杂性。

 Android 开发文档中说明Log.d和Log.v只有在开发版本中输出,在Release版本中无输出。那么这个功能是如何实现的呢?Android中Log.d和Log.v在Java和Native Code有不同的实现,需要分别说明。

1. native code中实现

    我们知道C/C++版本编译的时候会有release/debug 编译参数可以选择,所以在native code中可以根据不同的编译宏开关参数实现。

#ifndef LOGV
#if LOG_NDEBUG
#define LOGV(...)   ((void)0)
#else
#define
LOGV(...) ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#endif
#endif

2. Java代码中实现

Java的编译器就没有C/C++编译宏参数的功能,所以只能通过最原始的方法,写两个不同实现文件,在Make File 中根据编译参数不同进行COPY源代码的动作。大家可以在frameworks/base/Android.mk中查找实现方法。

其实在Java代码中,如果使用直接使用Log.v的方式输入trace,那么无论是Debug版本还是Release版本都还是会有Log输出的。文档所讲的,在Release版本中Verbose是不输出,在Android原始代码中使用下面的方式实现。

 if (Config.LOGV) Log.v(TAG, "<<< Releasing cursor " + this);

Config.LOGV的最值是最终是根据ConfigBuildFlags.java文件,而ConfigBuildFlags.java是在Android.mk中进行控制的。

 

# Include a different set of source files when building a debug build.
# TODO: Maybe build these into a separate .jar and put it on the classpath
#       in front of framework.jar.
# NOTE: Do not use this as an example; this is a very special situation.
#       Do not modify LOCAL_SRC_FILES based on any variable other
#       than TARGET_BUILD_TYPE, otherwise builds can become inconsistent.
ifeq ($(TARGET_BUILD_TYPE),debug)
  LOCAL_SRC_FILES += $(call find-other-java-files,core/config/debug)
else
  LOCAL_SRC_FILES += $(call find-other-java-files,core/config/ndebug)
endif

 

即使在Android2.2之后有增加Slog.java这样的类,在实现Log.v的控制的时候也是采用了Config.LOGV来做判断条件。由于每次写输出Log的时候都需要加上这样的判断,还真是有点痛苦哦。是否可以将Log.java 和 Slog.java进行下面的优化。

 

  public static int v(String tag, String msg) {

       if (Config.LOGV)
        return Log.println_native(Log.LOG_ID_SYSTEM, Log.VERBOSE, tag, msg);

       else 

       return 0;
    }

    public static int v(String tag, String msg, Throwable tr) {

        if (Config.LOGV) 
        return Log.println_native(Log.LOG_ID_SYSTEM, Log.VERBOSE, tag,
                msg + '\n' + Log.getStackTraceString(tr));

      else

       return 0;
    }

 

 

<think> 首先,用户的问题是关于在Android root版本上是否能打印Log.d中的日志。Log.d是Android中用于调试级别的日志,通常通过Logcat查看。 我需要回顾提供的引用: - 引用[1]:描述了在Android手机上启用Logcat日志的步骤,通过拨号代码进入服务菜单设置LOG开关级别。 - 引用[2]:解释了日志级别,包括INFO、DEBUG等,并提到配置可以控制哪些级别的日志被打印。 - 引用[3]:提到在发布版本release build)中,Android框架会隐藏一些日志消息;只有在调试版本(debug build)中才能显示。还提到即使是root手机也无法显示。 - 引用[4]:似乎是关于Logcat行缺失的分析,但内容完整。 用户的问题核心是:在root版本Android上,是否能打印Log.d(DEBUG级别)的日志。 关键点: - Root权限允许用户访问系统文件,但一定能改变日志打印行为。 - 根据引用[3],在发布版本中,DEBUG级别的日志通常被过滤掉,无法显示,即使是root手机也无济于事。这是因为在编译时,日志级别被优化掉了。 在Android中,日志级别由编译时的配置决定: - 在调试版本(debug build)中,Log.d日志会被打印。 - 在发布版本release build)中,Log.d日志通常被编译优化掉,输出Logcat,以节省资源提高性能。 Root权限可以让用户修改系统设置,但改变日志行为涉及到底层框架。引用[1]提到通过拨号代码设置LOG开关,这可能在某些设备上有效,但依赖于设备制造商的具体实现。 引用[3]明确说:"the Android framework hides some log messages if you have a release build of your firmware. To show those you need to recompile your firmware as debug build. No chance to get those to show on a rooted phone either." 这表明,即使是root手机,也无法在发布版本中显示DEBUG日志;必须重新编译为调试版本。 因此,我的回答应基于此: - 解释日志级别的概念。 - 说明在发布版本中,Log.d日志通常被打印。 - Root权限可能允许修改一些设置(如引用[1]),但无法强制在发布版本中打印DEBUG日志。 - 建议如果需要DEBUG日志,应使用调试版本或调整日志级别。 回答结构: 1. **介绍问题**:简要重述用户问题。 2. **解释日志级别**:使用引用[2]的信息,说明同日志级别的含义。 3. **讨论root版本的影响**:基于引用[3],解释root权限是否帮助。 4. **提供解决方案**:如果可能,如何在root手机上尝试启用日志,但强调局限性。 5. **引用来源**:自然地添加引用标识。 系统指令要求: - 使用$...$格式的行内数学表达式(但这个问题涉及数学,所以可能需要)。 - 独立公式用$$...$$(同样,适用)。 - LaTeX语法正确(涉及)。 - 使用中文回答。 - 生成相关问题。 - 在引用段落末尾添加引用标识。 - 回答结构清晰,真实可靠。 最后,生成相关问题。 </think>### Android root版本能否打印Log.d中的日志 在Android开发中,使用`Log.d()`方法输出的DEBUG级别日志(如`Log.d(TAG, "调试信息")`)是开发调试的重要工具。但在root版本Android系统上,能否打印出这些日志取决于多个因素。下面我将一步步解释这个问题,帮助您理解其原理解决方法。 #### 1. **Android日志级别的基本概念** - Android日志分为多个级别,包括`VERBOSE`、`DEBUG`、`INFO`、`WARN`、`ERROR``FATAL`。其中,`DEBUG`级别(对应`Log.d()`)通常用于开发调试阶段。 - 在日志系统中,日志输出由编译时配置决定: - **调试版本 (Debug Build)**:默认启用所有日志级别,包括`DEBUG`。 - **发布版本 (Release Build)**:为优化性能安全,`DEBUG`级别日志通常被编译优化掉(即输出Logcat),即使代码中包含`Log.d()`调用[^3]。 - 日志级别可通过配置文件或系统设置调整,例如,设置级别为`INFO`时,`DEBUG`日志会被显示[^2]。 #### 2. **Root权限对日志打印的影响** Root权限让用户获得系统级访问能力,但它 **一定能强制打印发布版本中的`DEBUG`日志**: - **限制性原因**: - 在发布版本Android固件中,`DEBUG`日志通常在编译时被框架主动隐藏或移除,以节省资源。Root权限无法改变编译时的优化行为(例如,日志代码可能已被删除或禁用)[^3]。 - 即使root用户修改系统设置(如通过拨号代码`*#*#2846579#*#*`启用LOG开关),这也只对部分设备有效,且可能仅限于`INFO`或更高级别的日志,无法强制恢复`DEBUG`日志[^1][^3]。 - **可能的情况**: - 如果设备运行的是 **调试版本固件**,root权限可以轻松启用所有日志级别(例如,通过修改`/system/build.prop`文件或使用终端命令)。 - 在 **发布版本固件** 上,即使root权限允许您调整日志级别(如设置级别为`DEBUG`),但底层框架的优化可能使`Log.d()`调用无效,导致日志输出[^3][^4]。 - 总结:Root权限 **能保证** 在发布版本中打印`DEBUG`日志;它仅能提高访问权限,但无法绕过编译优化。 #### 3. **如何尝试在root设备上打印`DEBUG`日志** 尽管有局限性,您可以尝试以下方法(注意:效果因设备固件版本而异): - **方法1: 通过系统菜单启用日志** - 在root设备上,尝试拨号输入`*#*#2846579#*#*`进入服务菜单。 - 选择“ProjectMenu” → “后台设置” → “Log 设置”,将LOG开关设为“开”。 - 再进入“Log 级别设置”,设为`DEBUG`或`ALL`(如果选项可用)。 - 重启设备后检查Logcat(在Android Studio或ADB中)。注意:此方法在部分厂商设备上可能有效,但无法保证`DEBUG`日志被实际打印[^1][^3]。 - 示例ADB命令: ```bash adb logcat *:D # 设置Logcat过滤器为DEBUG级别 ``` - **方法2: 修改系统配置文件(需要root)** - 使用root文件管理器或终端应用,编辑`/system/build.prop`文件: ```bash su # 获取root权限 mount -o remount,rw /system # 挂载系统为可写 echo "persist.log.tag=DEBUG" >> /system/build.prop # 添加日志级别配置 reboot # 重启设备 ``` - 重启后,检查Logcat输出。但此方法可能无效,因为发布版本固件可能已移除`DEBUG`日志支持[^3]。 - **推荐方法: 使用调试版本固件** - 如果需要可靠打印`DEBUG`日志,最佳方案是刷入调试版本的固件(如通过编译AOSP源码生成)。调试版本默认启用所有日志级别,无需root也能输出`Log.d()`日志[^3]。 - 替代方案:在代码中使用更高日志级别(如`Log.i()` for INFO),因为INFO级别在发布版本中通常可见[^2]。 #### 4. **总结建议** - **在root设备上**:您可以尝试启用日志设置,但 **无法强制打印发布版本中的`DEBUG`日志**。Root权限主要用于访问系统文件,而非改变编译优化。 - **一般情况**:如果设备运行发布版本固件,`Log.d()`日志通常被隐藏;调试版本固件是唯一可靠方案。 - **调试提示**:始终在开发阶段使用调试构建(debug build)进行测试,以避免日志问题。 如果您有特定设备型号或固件信息,我可以提供更针对性的建议!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值