从Android中的生产代码中删除日志记录?

时间:2012-04-24 18:53:39

标签: android

从生产Android应用程序中删除日志记录的最佳方法是什么。似乎proguard没有完全做到这一点,字符串仍然写入,所以我想知道从生产代码中删除日志记录的最佳解决方案是什么?

8 个答案:

答案 0 :(得分:24)

IMO最佳解决方案是在您调用日志记录方法的任何地方编写如下代码。

if (SOME_LOG_CONSTANT) Log.d(TAG, "event:" + someSlowToEvaluateMethod());

通过更改1常量,您将删除每个不需要的日志记录。这样,if (false)后面的部分甚至不应该进入你的.class文件,因为编译器可以完全删除它(它是无法访问的代码)。

这也意味着如果将它们包装在if中,则可以从发布软件中排除整个代码块。这甚至是一些无法做到的事情。

如果您使用SDK Tools r17及更高版本,则SOME_LOG_CONSTANT可以是BuildConfig.DEBUG。根据构建类型,该常量会自动更改。 Thx @Christopher

答案 1 :(得分:9)

使用Timber,它是一个很好的库来配置您的日志: https://github.com/JakeWharton/timber

使用示例:Timber.d("活动创建");

配置示例:

public class ExampleApp extends Application {
  @Override public void onCreate() {
   super.onCreate();

    if (BuildConfig.DEBUG) {
     Timber.plant(new DebugTree());
    } else {
     Timber.plant(new CrashReportingTree());
    }
  }




/** A tree which logs important information for crash reporting. */
 private static class CrashReportingTree extends Timber.Tree {
   @Override protected void log(int priority, String tag, String message, Throwable t) {
     if (priority == Log.VERBOSE || priority == Log.DEBUG) {
       return;
     }

     FakeCrashLibrary.log(priority, tag, message);

     if (t != null) {
       if (priority == Log.ERROR) {
         FakeCrashLibrary.logError(t);
       } else if (priority == Log.WARN) {
         FakeCrashLibrary.logWarning(t);
       }
     }
   }
 }

答案 2 :(得分:6)

Configuring Your Application for Release告诉您在发布应用程序之前只需删除Log命令。

  

您可以通过删除源文件中对Log方法的调用来停用日志记录。

我所做的是创建一个专有的静态日志方法,该方法读取类似这样的全局布尔值:

class MyLog {

    private static final boolean LOGGING = true; //false to disable logging

    public static void d(String tag, String message) {
        if (LOGGING) {
            Log.d(tag, message);
        }
    }

    /* ... same for v, e, w, i */
}

在您想要记录的任何地方使用它。

MyLog.d("Tag", "This will only work with LOGGING true");

答案 3 :(得分:1)

我建议你看看Log extension class

它使您可以对日志进行精细控制。 例如,您可以禁用所有日志(感谢配置文件)或仅禁用某些包或类的日志。

此外,它添加了一些有用的功能(例如,您不必为每个日志传递标记)。

答案 4 :(得分:0)

我建议您查看Roboguice - http://code.google.com/p/roboguice/ - 如果您使用内置的Ln功能,它将自动无法登录已签名的APK。它还简化了大量其他Android样板。你可以在使用基线 - https://github.com/achuinard/basedroid

的情况下看到它

答案 5 :(得分:0)

您可以使用DebugLog课程。释放应用程序时,DebugLog会禁用所有日志。它为开发人员提供了更易理解的DDMS日志。

实施例

DebugLog.e("your message");

答案 6 :(得分:0)

只需将此方法添加到您的代码中,然后使用Logd而不是Log.d

private static final String TAG = "your own tag to recognize log entries from this app";

public static void Logd(String txt) {
    if (BuildConfig.DEBUG&&BuildConfig.BUILD_TYPE.equals("debug")) Log.d(TAG,txt);
}

我知道仍会对字符串进行评估,但我们正在谈论额外处理时间内的微秒。没有人会注意到应用程序速度的差异,除非您在循环中进行了数千次记录。

DEBUG和BUILD_TYPE可在Android Studio中使用。 DEBUG布尔值是build.gradle文件中的“debuggable”选项:

buildTypes {
    debug {
        debuggable true
        runProguard false
        proguardFile getDefaultProguardFile('proguard-android.txt')
    }
    release {
        debuggable false
        runProguard true
        proguardFile getDefaultProguardFile('proguard-android.txt')
    }
}

在Android Studio中运行时,BUILD_TYPE会自动设置为“debug”。

因此,如果您将debuggable设置为false或者用户具有发布版本,那么日志将会消失。

答案 7 :(得分:0)

最好的方法是根据我的经验来处理这个问题,

  • 首先记录检查BuildConfig.DEBUG标志以打印日志。

    Class LogUtils{
    
        public static void log(Class clazz, String message) {
            if (BuildConfig.DEBUG) {//log only in debug mode
            Log.d(clazz.getSimpleName(), message);
            }
        }
    }
    
  • 然后启用minify到您的app模块gradle文件,这将使proguard优化您的二进制文件

    android {
        buildTypes {
            release {
                minifyEnabled true
                //shrinkResources true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                signingConfig signingConfigs.release
            }
        }
    }
    

这会将调试日志保留在调试版本中。 但是在您的发布版本中,if (BuildConfig.DEBUG)条件永远不会成立,因此proguard将从二进制文件中删除无法访问的日志代码。