【问题标题】:Using Log.d() or Log.e() in my code在我的代码中使用 Log.d() 或 Log.e()
【发布时间】:2011-11-10 23:20:52
【问题描述】:

我在整个安卓应用程序中都使用了Log.d()Log.e() 来进行调试。 我想知道如果我这样发布我的应用程序,用户会看到我输入的所有调试语句吗?我是否需要做一些特别的事情,以便用户即使连接了 'adb logcat' 也不会看到调试日志?

谢谢。

【问题讨论】:

    标签: android


    【解决方案1】:

    在某些情况下,留下日志语句可能会非常糟糕: http://web.archive.org/web/20121222023201/http://vbsteven.com/archives/535

    您可以使用 ProGuard 自动将它们全部删除:

    -assumenosideeffects class android.util.Log {
        public static *** d(...);
        public static *** e(...);
    }
    

    【讨论】:

    • 您引用的博文连同整个博客已被删除。作者这样说:“所以我决定重新开始。新内容、新博客引擎和新设计”
    • 谢谢,我用存档版本替换了链接。
    • 谢谢。在发布我的应用程序之前,我正在了解有关日志记录的更多信息。这篇文章很有帮助。
    【解决方案2】:

    考虑使用这个:isLoggable()

    检查指定标签的日志是否可在指定级别记录。任何标签的默认级别都设置为 INFO。这意味着将记录任何高于并包括 INFO 的级别。在您对记录方法进行任何调用之前,您应该检查是否应该记录您的标签。您可以通过设置系统属性来更改默认级别:setprop log.tag.<YOUR_LOG_TAG> <LEVEL> 其中 level 是 VERBOSE、DEBUG、INFO、WARN、ERROR、ASSERT 或 SUPPRESS。 SUPPRESS 将关闭您的标签的所有日志记录。您还可以创建一个包含以下内容的 local.prop 文件:log.tag.<YOUR_LOG_TAG>=<LEVEL> 并将其放在 /data/local.prop

    就个人而言,我会删除调试日志并使用 Proguard 保留错误日志。


    最好这样包装:

    public class MyLog {
    
    public static void d(String tag, String msg) {
       if (Log.isLoggable(tag, Log.DEBUG)) {
           Log.d(tag, msg);
    }
    }
    
    public static void i(String tag, String msg) {
        if (Log.isLoggable(tag, Log.INFO)) {
         Log.i(tag, msg);
    }
    }  // and so on... 
    

    你可以设置日志级别by issuing an adb command

    【讨论】:

    • 谢谢。你能帮我们理解 isLoggable() 的用法吗?我有这样的代码 Log.d(MYTAG, "debug statement");使用 isLoggable() 是否意味着我需要做 'if isLoggable(MYTAG, Log.DEBUG) { Log.d(MYTAG, "debug statment"); ' 无处不在?
    • 我已经修改了我的答案。 Krylez 的解决方案是最好的,这只是一个替代方案。
    【解决方案3】:

    不仅用户(或任何具有日志访问权限的应用)可以查看您的日志,而且您的日志还会导致您的应用运行速度变慢并使用更多电池电量。

    编写日志,尤其是从 Java 编写日志,可能比您想象的要昂贵得多:仅在 Java 中构建字符串需要大量工作。

    【讨论】:

    • 谢谢。我在如何在我的 build.xml 文件中为 android 项目使用 Proguard 中阅读了这个 android-developers.blogspot.com/2010/09/…。但它没有说明如何使用 Proguard 来剥离对 Log.d 和 Log.e 的所有调用。你能告诉我我该怎么做吗?
    【解决方案4】:

    市场中有一些应用程序允许用户在不连接开发环境的情况下查看日志。

    CatLog 是我个人使用过的,它会告诉你一切。

    我在我的应用程序中所做的是创建一个包装类,我可以用一个布尔标志关闭自己。它的另一个好处是让 TAG 参数成为我的代码的通用吞吐量。

    public class QLog {
        private static final String TAG = "MyAppTag";
        private static final boolean DEBUG_MODE = true;
    
        public static void d(String msg) {
            if(DEBUG_MODE) {
                Log.d(TAG, msg);
            }
        }
        ...
    }
    

    【讨论】:

      【解决方案5】:

      正如 android.developer.com 中所说的那样

      当您构建要传递给 Log.d 的字符串时,编译器使用 StringBuilder 并且至少会发生三个分配:StringBuilder 本身、缓冲区和 String 对象。现实中,还有另外一个缓冲区分配和复制,对gc的压力更大。这意味着,如果您的日志消息被过滤掉,您可能会做大量工作并产生大量开销。

      这里是链接: http://developer.android.com/reference/android/util/Log.html

      【讨论】:

        【解决方案6】:

        它们可以在开发时使用。发布时,最好删除或混淆消息以保护 PII(个人身份信息)。这里的答案很有用:Android Log.v(), Log.d(), Log.i(), Log.w(), Log.e() - When to use each one?

        这里教你发布软件时处理这些日志的工具。Remove all debug logging calls before publishing: are there tools to do this?

        【讨论】:

          【解决方案7】:

          如果您的用户是开发人员,并且将设备连接到开发机器并打开了 LogCat,如果他与该应用程序交互,他将在 Logcat 上查看所有日志。当您要将应用程序发布给最终用户时,您应该删除这些日志。

          【讨论】:

          • 所以如果我构建一个“发布”版本,它不会让那些 Log.d() 自动什么都不做?
          【解决方案8】:

          日志记录指南

          Log.v(String tag, String msg) (verbose)
          Log.d(String tag, String msg) (debug)
          Log.i(String tag, String msg) (information)
          Log.w(String tag, String msg) (warning)
          Log.e(String tag, String msg) (error)
          
          To only show logs on debug builds:
          
          if (BuildConfig.DEBUG) Log.d(TAG, "The value of x is " + x);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-12-19
            • 1970-01-01
            • 2017-01-28
            • 1970-01-01
            • 1970-01-01
            • 2014-05-01
            • 1970-01-01
            相关资源
            最近更新 更多