根据谷歌的说法,我必须在发布我的Android应用程序之前“停用对源代码中任何Log方法的调用” . 摘自publication checklist的第5部分:
在构建应用程序以进行发布之前,请确保停用日志记录并禁用调试选项 . 您可以通过删除源文件中对Log方法的调用来停用日志记录 .
我的开源项目很大,每次发布时手动执行都很痛苦 . 此外,删除日志行可能很棘手,例如:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
如果我注释Log行,那么条件适用于下一行,并且很可能没有调用load() . 这种情况是否足够罕见,我可以决定它不应该存在?
这是在官方清单上,所以我想很多人会定期这样做 .
那么,如何有效但安全地删除所有日志行?
21 回答
我喜欢使用Log.d(TAG,一些字符串,通常是String.format()) .
TAG始终是 class 名称
转换Log.d(TAG, - > Logd(在您的课程文本中)
这样,当您准备好发布版本时,将MainClass.debug设置为false!
我会考虑使用roboguice的logging facility而不是内置的android.util.Log
他们的工具会自动禁用发布版本的调试和详细日志 . 此外,您还可以免费获得一些漂亮的功能(例如,可自定义的日志记录行为,每个日志的附加数据等)
使用proguard可能会非常麻烦,除非你有充分的理由(禁用日志不是很好),否则我不会遇到使用你的应用程序进行配置和制作 work 的麻烦 .
我有一个非常简单的解决方案 . 我使用IntelliJ进行开发,因此细节会有所不同,但这个想法应该适用于所有IDE .
我选择了源树的根,右键单击并选择“替换” . 然后我选择替换所有“日志” . 用“// Log . ” . 这将删除所有日志语句 . 为了稍后再重复,我重复相同的替换,但这次更换所有“// Log” . 用“Log . ” .
对我来说非常棒 . 只需记住将替换设置为区分大小写以避免诸如“Dialog”之类的事故 . 为了进一步保证,您还可以使用“日志”执行第一步 . 作为要搜索的字符串 .
辉煌 .
我发现一个更容易的解决方案是忘记所有
if
检查,只需使用ProGuard去掉我们调用Antrelease
目标时的任何Log.d()
或Log.v()
方法调用 .这样,我们总是为常规构建输出调试信息,而不必为发布版本进行任何代码更改 . ProGuard还可以对字节码执行多次传递,以删除其他不需要的语句,空块,并可以在适当的情况下自动内联短方法 .
例如,这是一个非常基本的Android ProGuard配置:
因此,您可以将其保存到文件中,然后从Ant调用ProGuard,传入刚刚编译的JAR和您正在使用的Android平台JAR .
另请参阅ProGuard手册中的the examples .
Update (4.5 years later): 如今我使用Timber进行Android日志记录 .
它不仅比默认的
Log
实现更好 - 日志标记是自动设置的,并且很容易记录格式化的字符串和异常 - 但您也可以在运行时指定不同的日志记录行为 .在此示例中,日志记录语句将仅在我的应用程序的调试版本中写入logcat:
Timber在我的
Application
onCreate()
方法中设置:然后我的代码中的任何其他地方都可以轻松记录:
有关更高级的示例,请参阅Timber sample app,其中所有日志语句在开发期间发送到logcat,在 生产环境 中,不会记录任何调试语句,但会向Crashlytics静默报告错误 .
我在Google IO示例应用程序中使用了LogUtils类 . 我将其修改为使用特定于应用程序的DEBUG常量而不是BuildConfig.DEBUG,因为BuildConfig.DEBUG is unreliable . 然后在我的课程中,我有以下内容 .
这是我以前在我的android项目上做的事情..
在Android Studio中,我们可以通过Ctrl Shift F从整个项目(MacOs中的Command Shift F)和Ctrl Shift R替换((MacO中的命令Shift R))进行类似操作
如果你可以运行全局替换(一次),之后保留一些编码约定,你可以遵循Android framework中经常使用的模式 .
而不是写作
有它作为
现在,proguard可以从优化的版本DEX中删除StringBuilder以及它在途中使用的所有字符串和方法 . 使用
proguard-android-optimize.txt
,您无需担心proguard-rules.pro
中的android.util.Log:使用Android Studio gradle插件,
BuildConfig.DEBUG
非常可靠,因此您无需额外的常量来控制剥离 .所有好的答案,但是当我完成我的开发时,我不想使用围绕所有Log调用的if语句,也不想使用外部工具 .
所以我使用的解决方案是用我自己的Log类替换android.util.Log类:
我在所有源文件中唯一要做的就是替换导入android.util.Log与我自己的类 .
我建议有一个静态布尔值,指示是否记录:
然后,无论您想要在哪里登录代码,只需执行以下操作:
现在,当您将MyDebug.LOG设置为false时,编译器将删除此类检查中的所有代码(因为它是静态final,它在编译时知道不使用代码 . )
对于较大的项目,您可能希望在单个文件中开始使用布尔值,以便能够根据需要轻松启用或禁用日志记录 . 例如,这些是我们在窗口管理器中具有的各种日志记录常量:
使用相应的代码:
我知道这是一个老问题,但为什么不用布尔logCallWasHere = true替换所有的日志调用; // ---你的其余日志在这里
这就是为什么你会知道什么时候你想把它们放回去,它们不会影响你的if语句调用:)
Christopher的Proguard解决方案是最好的,但如果出于任何原因你不喜欢Proguard,这是一个非常低技术的解决方案:
评论日志:
取消注释日志:
约束是您的日志记录说明不得跨越多行 .
(在项目根目录的UNIX shell中执行这些行 . 如果使用Windows,获取UNIX层或使用等效的Windows命令)
我发布的此解决方案专门适用于Android Studio用户 . 我最近还发现了Timber并通过以下方式将其成功导入我的应用程序:
将最新版本的库放入build.gradle:
然后在Android工作室中,转到编辑 - >查找 - >替换路径...
输入
Log.e(TAG,
或者您已将日志消息定义到"Text to find"
文本框中 . 然后你只需用Timber.e(
替换它单击查找,然后单击全部替换 .
Android工作室现在将浏览项目中的所有文件,并将所有日志替换为Timbers .
我使用这种方法的唯一问题是gradle后来出现了数百万条错误消息,因为它无法在每个java文件的导入中找到“Timber” . 只需点击错误,Android Studios就会自动将“Timber”导入您的java . 完成所有错误文件后,gradle将再次编译 .
您还需要将这段代码放在
Application
类的onCreate
方法中:这将导致应用程序仅在您处于开发模式而非 生产环境 模式时进行日志记录 . 您还可以使用
BuildConfig.RELEASE
登录发布模式 .最简单的方法;
使用
DebugLog
应用程序发布时,DebugLog会禁用所有日志 .
https://github.com/MustafaFerhan/DebugLog
正如zserge's comment建议的那样,
his log library提供简单的启用/禁用日志打印开关,如下所示 .
此外,它只需要更改
import
行,并且Log.d(...);
语句不需要更改 .我想添加一些关于在Android Studio和gradle中使用Proguard的精度,因为我从最终的二进制文件中删除日志行有很多问题 .
为了在Proguard作品中制作
assumenosideeffects
,有一个先决条件 .在gradle文件中,您必须将
proguard-android-optimize.txt
的用法指定为默认文件 .实际上,在默认的
proguard-android.txt
文件中,使用两个标志禁用优化:proguard-android-optimize.txt
文件不会添加这些行,所以现在assumenosideeffects
可以工作 .然后,在我开发一些分发给其他人的库时,我还会使用SLF4J . 优点是默认情况下没有输出 . 如果集成商需要一些日志输出,他可以使用Logback for Android并激活日志,因此可以将日志重定向到文件或LogCat .
如果我真的需要从最终库中删除日志,那么我会添加到我的Proguard文件中(当然在启用了
proguard-android-optimize.txt
文件之后):将以下内容添加到 proguard-rules.txt 文件中
ProGuard将在您的发布版本上为您完成,现在来自android.com的好消息:
http://developer.android.com/tools/help/proguard.html
ProGuard工具通过删除未使用的代码并使用语义模糊的名称重命名类,字段和方法来缩小,优化和混淆代码 . 结果是较小的.apk文件,更难以进行逆向工程 . 由于ProGuard使您的应用程序更难以进行逆向工程,因此当您的应用程序使用对安全性敏感的功能时(如您正在许可您的应用程序 .
ProGuard已集成到Android构建系统中,因此您无需手动调用它 . 只有在发布模式下构建应用程序时,ProGuard才会运行,因此在调试模式下构建应用程序时,不必处理混淆代码 . ProGuard运行是完全可选的,但强烈建议 .
本文档介绍了如何启用和配置ProGuard,以及如何使用回扫工具解码混淆的堆栈跟踪
可以使用linux和sed中的bash删除日志:
适用于多行日志 . 在此解决方案中,您可以确定 生产环境 代码中不存在日志 .
我强烈建议使用杰克沃顿的木材
https://github.com/JakeWharton/timber
它解决了启用/禁用问题以及自动添加标记类的问题
只是
日志只会在您的调试版中使用,然后使用
要么
打印
“你的课程/ msg”没有指定标签
每个android.util.Log提供了一种启用/禁用日志的方法:
默认方法isLoggable(...)返回false,只有在设备中的setprop之后才会这样:
这意味着可以打印任何DEBUG级别以上的日志 . 参考android doc:
所以我们可以使用自定义日志工具:
我通过提供对不同日志级别的支持以及根据代码是在实时设备上运行还是在模拟器上自动更改日志级别来改进上述解决方案 .