据谷歌称,在发布我的Android应用程序之前,我必须" 停用源代码中对Log方法的任何调用 ".摘录自出版物清单的第5部分:
在构建应用程序以进行发布之前,请确保停用日志记录并禁用调试选项.您可以通过删除源文件中对Log方法的调用来停用日志记录.
我的开源项目很大,每次发布时手动执行都很痛苦.此外,删除日志行可能很棘手,例如:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
Run Code Online (Sandbox Code Playgroud)
如果我对日志行进行注释,则条件适用于下一行,并且可能不会调用load().这种情况是否足够罕见,我可以决定它不应该存在?
这是在官方清单上,所以我想很多人会定期这样做.
那么,如何有效但安全地删除所有日志行?
我有很多日志语句要调试,例如.
Log.v(TAG, "Message here");
Log.w(TAG, " WARNING HERE");
Run Code Online (Sandbox Code Playgroud)
在设备电话上部署此应用程序时,我想关闭可以启用/禁用日志记录的详细日志记录.
我正在尝试使用proguard来删除所有日志:我在proguard-project.txt中输入了以下行:
-assumenosideeffects class android.util.Log { *; }
Run Code Online (Sandbox Code Playgroud)
我的project.properties看起来像这样:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
Run Code Online (Sandbox Code Playgroud)
尽管如此,日志仍然会在我的申请中显示出来.我到底错在了什么?
从生产android应用程序中删除日志记录的最佳方法是什么.似乎proguard没有完全做到这一点,字符串仍然写入,所以我想知道从生产代码中删除日志记录的最佳解决方案是什么?
可能重复:
在ProGuard优化期间删除未使用的字符串
我有一个包含许多日志语句的Android应用程序.我希望它们不会出现在发布版本中,所以我在proguard.cfg文件中使用了Proguard这样的东西:
-assumenosideeffects class android.util.Log {
public static *** d(...);
}
Run Code Online (Sandbox Code Playgroud)
但问题是有很多Log.d("something is " + something),虽然Log.d()语句正在从字节码中删除,但字符串仍然存在.
所以,按照这个答案,我创建了一个简单的包装类,类似于:
public class MyLogger {
public static void d(Object... msgs) {
StringBuilder log = new StringBuilder();
for(Object msg : msgs) {
log.append(msg.toString());
}
Log.d(TAG, log.toString());
}
}
Run Code Online (Sandbox Code Playgroud)
然后我编辑了我proguard.cfg:
-assumenosideeffects class my.package.MyLogger {
public static *** d(...);
}
Run Code Online (Sandbox Code Playgroud)
但是仍然可以在生成的字节码中找到字符串!
除此之外,我使用的proguard.cfg是Android SDK提供的标准.难道我做错了什么?
编辑:在检查生成的字节码之后,我看到字符串在那里,但它们并没有像我想的那样相互追加.它们存储在一个数组中.为什么?将它们作为变量参数传递给我的方法.看起来ProGuard不喜欢这样,所以我修改了我的记录器类,如下所示:
public static void d(Object a) …Run Code Online (Sandbox Code Playgroud) 我有一个带有静态日志记录方法的类,例如:
我正在尝试使用 ProGuard 删除所有这些。我不想只是禁用它们(无论如何都是使用逻辑完成的),我希望它们在反编译时消失。
它成功删除了对我的日志记录方法的调用,但留下了连接的字符串。它完全删除了固定的字符串。
这是我的 ProGuard 设置:
-assumenosideeffects class com.mypackage.Log { *; }
Run Code Online (Sandbox Code Playgroud)
这是我的来源:
void doSomething(String name) {
Log.verbose("Hello!");
Log.verbose("My name is " + name);
...
}
Run Code Online (Sandbox Code Playgroud)
这是它反编译的结果:
void a(String a) {
new StringBuilder("My name is ").append(a);
...
}
Run Code Online (Sandbox Code Playgroud)
这就是我希望它反编译为的内容:
void a(String a) {
...
}
Run Code Online (Sandbox Code Playgroud)
对于此示例,假设名称参数稍后在方法中使用(即,不应完全优化它)。
我还应该使用assumenosideeffectsStringBuilder 吗?我确实在其他地方使用了 StringBuilders,我确实想保留它。那会把它们也从那里删除吗?