Android Proguard 未删除所有日志消息

Posted

技术标签:

【中文标题】Android Proguard 未删除所有日志消息【英文标题】:Android Proguard not removing all log messages 【发布时间】:2012-09-05 14:36:24 【问题描述】:

我想创建一个混淆的 android 应用程序。我为此使用 ProGuard。我想自动删除所有 Log.* 消息。我怎样才能做到这一点?我找到了this 帖子,但我仍然得到它们。 (我使用反编译器检查混淆)。 proguard-project.txt 如下:

-injars       libs/In.jar
-outjars      libs/Out.jar
#-libraryjars  <java.home>/lib/rt.jar
-libraryjars C:/Users/thomas/android-sdks/platforms/android-7/android.jar

-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-keep public class * 
    public protected *;


-keepclassmembernames class * 
    java.lang.Class class$(java.lang.String);
    java.lang.Class class$(java.lang.String, boolean);


-keepclasseswithmembernames class * 
    native <methods>;


-keepclassmembers enum * 
    public static **[] values();
    public static ** valueOf(java.lang.String);


-keepclassmembers class * implements java.io.Serializable 
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();

-assumenosideeffects class android.util.Log 
    public static *** d(...);
    public static *** e(...);

任何帮助将不胜感激。 谢谢。

【问题讨论】:

【参考方案1】:

这只会删除所有调试Log.d(TAG, "..."); 和错误Log.e(TAG, "...") 调用:

-assumenosideeffects class android.util.Log 
    public static *** d(...);
    public static *** e(...);

要删除所有日志调用,只需使用以下命令:

-assumenosideeffects class android.util.Log  *; 

【讨论】:

警告:这样做会移除所有对象的 wait() 方法,因为 *;包括Log的所有方法,包括Object类的wait()!这肯定会导致奇怪的副作用。 永远不要做 -assumenosideeffects class android.util.Log *; 以避免副作用。新的R8也会很快报错【参考方案2】:

默认的 android Proguard 配置禁用优化。要启用它,请在项目的 project.properties 文件中使用 proguard-android-optimize.txt 而不是 proguard-android.txt

【讨论】:

【参考方案3】:

对于那些似乎无法完全理解职业后卫的人,你必须确保做两件事。

1:来自@yorkw

-assumenosideeffects class android.util.Log  *; 

2:来自@Gallal

在项目的 project.properties 文件中使用:

proguard.config=$sdk.dir/tools/proguard/proguard-android-optimize.txt:proguard-project.txt

而不是

proguard.config=$sdk.dir/tools/proguard/proguard-android.txt:proguard-project.txt

这是因为您有两个“开箱即用”的 proguard 选项,因为它们包含在 sdk 中

android-adk &gt; tools &gt; proguard

其中包含两个文件:

proguard-android.txt
proguard-android-optimize.txt

希望能对其他人有所帮助。

【讨论】:

project.properties 文件是(现在)称为local.properties? 如果您使用 android studio,我很确定现在一切都不同了。不要以为它甚至被称为proguard。认为它被称为“缩小”,它允许 proguard 运行。那就是说。这些说明仅适用于 ECLIPSE。 出于某种原因,我仍然在课堂上看到 Log 调用。 我发现日志调用只在release buildType中被移除【参考方案4】:

如果你有Android Studio,你必须修改你主应用的build.gradle

在您的 gradle 文件中,您必须指定 proguard-android-optimize.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-optimize.txt 文件没有添加这些行,所以现在assumenosideeffects 可以工作了。

然后,如 Eclipse 或其他答案中所述,您只需在主 proguard 文件中添加以下行:

-assumenosideeffects class android.util.Log 
    public static *** d(...);
    public static *** e(...);

【讨论】:

dontpreverify 与优化并不严格相关。 “只有在最终以 Android 为目标时,才没有必要,因此您可以将其关闭以减少处理时间。” guardsquare.com/en/products/proguard/manual/usage

以上是关于Android Proguard 未删除所有日志消息的主要内容,如果未能解决你的问题,请参考以下文章

在 ProGuard 优化期间删除未使用的字符串

使用 ProGuard 在 Android 中删除 LibGDX 日志

如何将 proguard 配置为仅删除 android 日志记录调用

Android Jack 编译器没有从 proguard 规则中删除日志

使用 proguard 删除日志调用

使用 ProGuard 删除日志不会删除正在记录的字符串 [重复]