从生产 android 应用程序中删除日志记录的最佳方法是什么。看来 proguard 并没有完全做到这一点,字符串仍然被写入,所以我想知道从生产代码中删除日志记录的最佳解决方案是什么?
8 回答
IMO 最好的解决方案是在调用日志记录方法的任何地方编写如下代码。
if (SOME_LOG_CONSTANT) Log.d(TAG, "event:" + someSlowToEvaluateMethod());
通过更改 1 个常量,您可以删除所有不需要的日志记录。这样后面的部分if (false)
甚至不应该进入您的 .class 文件,因为编译器可以完全删除它(它是无法访问的代码)。
这也意味着如果您将整个代码块包装在if
. 这是连proguard都做不到的。
如果您使用 SDK Tools r17 及更高版本,则可以SOME_LOG_CONSTANT
。BuildConfig.DEBUG
该常量会根据构建类型自动为您更改。谢谢@Christopher
使用 Timber,这是一个配置日志的好库: https ://github.com/JakeWharton/timber
使用示例:Timber.d("Activity Created");
配置示例:
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);
}
}
}
}
为发布配置您的应用程序告诉您在发布您的应用程序之前简单地删除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");
只需将此方法添加到您的代码中并使用 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 文件中的“可调试”选项:
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 会自动设置为“调试”。
因此,如果您将 debuggable 设置为 false 或用户拥有发布版本,那么日志将消失。
我建议您查看 Roboguice - http://code.google.com/p/roboguice/ - 如果您使用内置的 Ln 功能,它将自动不登录已签名的 APK。它还简化了大量其他 Android 样板。您可以使用 Basedroid 看到它的实际效果 - https://github.com/achuinard/basedroid
最好的方法是根据我的经验来处理这个问题,
首先在记录时检查 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 到您的应用程序模块 gradle 文件,这将使 proguard 能够优化您的二进制文件
android { buildTypes { release { minifyEnabled true //shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } } }
这将在您的调试版本中保留调试日志。但是在您的发布版本中,if (BuildConfig.DEBUG)
条件永远不会成立,因此 proguard 将从您的二进制文件中删除无法访问的日志代码。