根据谷歌,我必须在发布我的Android应用程序谷歌播放之前“停用源代码中的Log方法的任何调用”。出版清单第3节节选:
在构建应用程序发布之前,请确保禁用了日志记录并禁用了调试选项。您可以通过删除源文件中对Log方法的调用来禁用日志记录。
我的开源项目很大,每次发布都要手动完成,这很痛苦。此外,删除Log行可能很棘手,例如:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
如果注释Log行,则该条件将应用于下一行,并且可能不会调用load()。这样的情况是否罕见到我可以决定它不应该存在?
那么,是否有更好的源代码级方法来做到这一点呢?或者是一些聪明的ProGuard语法,有效但安全地删除所有Log行?
我想添加一些关于使用Proguard与Android Studio和gradle的精度,因为我有很多问题,从最终的二进制文件中删除日志行。
为了使保护工作中的副作用假设,有一个先决条件。
在你的gradle文件中,你必须指定proguard-android- optimization .txt作为默认文件。
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// With the file below, it does not work!
//proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
实际上,在默认的proguard-android.txt文件中,通过以下两个标志禁用了优化:
-dontoptimize
-dontpreverify
proguard-android- optimization .txt文件没有添加这些行,所以现在假设副作用可以工作。
然后,就我个人而言,我使用SLF4J,特别是当我开发一些分发给其他人的库时。其优点是默认情况下没有输出。如果积分器想要一些日志输出,他可以使用Android的Logback并激活日志,这样日志就可以重定向到文件或LogCat。
如果我真的需要从最终库中剥离日志,我就会添加到我的Proguard文件中(当然是在启用了Proguard -android- optimization .txt文件之后):
-assumenosideeffects class * implements org.slf4j.Logger {
public *** trace(...);
public *** debug(...);
public *** info(...);
public *** warn(...);
public *** error(...);
}
如果你可以运行全局替换(一次),然后保留一些编码惯例,你可以遵循Android框架中经常使用的模式。
而不是写作
Log.d(TAG, string1 + string2 + arg3.toString());
把它当作
if (BuildConfig.DEBUG) Log.d(TAG, string1 + String.format("%.2f", arg2) + arg3.toString());
现在proguard可以从优化版的DEX中删除StringBuilder和它使用的所有字符串和方法。使用proguard-android- optimization .txt,你就不用担心android.util了。
android {
…
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
与Android Studio gradle插件,BuildConfig。DEBUG非常可靠,因此不需要额外的常数来控制剥离。
我在我的项目中使用了以下方法
创建自定义记录器类:
public class LoggerData
{
public static void showLog(String type, Object object) {
try {
Log.d("loggerData:" + type + "-", "showLog: " + new Gson().toJson(object));
} catch (Exception e) {
Log.d("TAG", "showLog: " + e.getLocalizedMessage());
Log.d("loggerData:" + type + "-", "showLog: " + object);
}
}
public static void showLog(Object object) {
try {
Log.d("loggerData:" + "-", "showLog: +" + new Gson().toJson(object));
} catch (Exception e) {
Log.d("TAG", "showLog: " + e.getLocalizedMessage());
Log.d("loggerData:" + "-", "showLog: " + object);
}
}
}
然后每当需要登录代码时,就像这样使用
LoggerData.showLog("Refreshed token: ", token);
在构建发布APK之前,在LoggerData类中只禁用一个地方的日志
例子
public class LoggerData {
public static void showLog(String type, Object object) {
try {
//Log.d("loggerData:" + type + "-", "showLog: " + new Gson().toJson(object));
} catch (Exception e) {
//Log.d("TAG", "showLog: " + e.getLocalizedMessage());
//Log.d("loggerData:" + type + "-", "showLog: " + object);
}
}
public static void showLog(Object object) {
try {
// Log.d("loggerData:" + "-", "showLog: +" + new Gson().toJson(object));
} catch (Exception e) {
//Log.d("TAG", "showLog: " + e.getLocalizedMessage());
//Log.d("loggerData:" + "-", "showLog: " + object);
}
}
}
希望它也能帮助到你。
我强烈建议使用Jake Wharton的Timber
https://github.com/JakeWharton/timber
它解决了您的问题,启用/禁用加添加标签类自动魔术
只是
public class MyApp extends Application {
public void onCreate() {
super.onCreate();
//Timber
if (BuildConfig.DEBUG) {
Timber.plant(new DebugTree());
}
...
日志将仅在调试版本中使用,然后使用
Timber.d("lol");
or
Timber.i("lol says %s","lol");
打印
“Your class / msg”,而不指定标签