问题

根据Google,在将我的Android应用程序发布到Google Play之前,我必须“取消对源代码中日志方法的任何调用”.从发布清单的第3节摘录:

确保您在构建应用程序以供发布之前取消激活日志记录并禁用调试选项.您可以通过删除源文件中对日志方法的调用来解除日志记录.

我的opensource项目很大,每次发布时手动执行它都很痛苦.此外,删除日志线可能很棘手,例如:

 if(condition)
  Log.d(LOG_TAG, "Something");
data.load();
data.show();
 

如果我评论日志行,那么条件适用于下一行,并且没有调用load()的机会.这种情况是否非常罕见,我可以决定不应该存在?

那么,是否有更好的源代码级方法来做到这一点?或者可能有一些聪明的ProGuard语法来有效但安全地删除所有日志行?

  最佳答案

我发现一个更简单的解决方案是忘记所有if检查所有地方,只是使用 ProGuard 脱去任何Log.d()Log.v()方法调用当我们调用我们的Ant release目标时.

这样,我们总是有正则构建的调试信息输出,不必为发布构建进行任何代码更改. Proguard也可以通过字节码进行多次传递,以删除其他不需要的语句,空块,并可以酌情自动内联短方法.

例如,这是Android的一个非常基本的ProGuard配置:

 -dontskipnonpubliclibraryclasses
-dontobfuscate
-forceprocessing
-optimizationpasses 5

-keep class * extends android.app.Activity
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}
 

所以您将它保存到文件中,然后从 Ant 调用 ProGuard,传递您正在使用的 JAR 和 Android 平台 JAR。

另见 ProGuard 手册中的示例


更新(4.5年后):现在我使用木材进行Android日志记录.

它不仅比默认的Log实现更好 – 日志标记自动设置,并且很容易记录格式化的字符串和异常 – 但您也可以在运行时指定不同的日志行为.

在这个例子中,日志语句只会在我的应用程序的调试构建中写入logcat:

木材在我的Application onCreate()方法中设置:

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

然后我的代码中的任何其他地方都可以轻松登录:

 Timber.d("Downloading URL: %s", url);
try {
  // ...
} catch (IOException ioe) {
  Timber.e(ioe, "Bad things happened!");
}
 

关于一个更高级的例子,请参阅 Mutch 示例应用程序 ,其中所有日志语句在开发过程中都被发送到 logcat,在生产过程中,没有记录调试语句,但错误被默默地报告给 Crashlytics。

  相同标签的其他问题

androidloggingproguardandroid-log