Android Proguard未能移除所有日志信息

24
我希望能创建一个混淆的Android应用程序。我使用ProGuard来实现。我想自动删除所有的Log.*消息。我该如何做?我找到了这篇文章,但我仍然得到它们。 (我使用反编译器来检查混淆)。
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(...);
}

任何帮助都将不胜感激。
谢谢。
4个回答

41

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

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

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

-assumenosideeffects class android.util.Log { *; }

1
警告:这样做将会移除所有对象的wait()方法,因为*;包括Log的所有方法,包括Object类中的wait()!这肯定会导致奇怪的副作用。 - 3c71
1
永远不要使用“assumenosideeffects”类android.util.Log { *; }来避免副作用。在新的R8中,这也将很快成为一个错误。 - Sinapse

18
默认的 Android Proguard 配置会禁用优化。要启用它,在您项目的 project.properties 文件中使用 proguard-android-optimize.txt 替代 proguard-android.txt。

12

对于那些似乎无法理解 ProGuard 的人,您必须确保做两件事。

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

这是因为您在SDK中有两个“开箱即用”的Proguard选项

android-adk > tools > proguard

其中包含两个文件:

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

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

“project.properties”文件现在被称为“local.properties”了吗? - Ivo Renkema
2
我非常确定,如果你使用的是Android Studio,现在一切都不同了。不认为它甚至被称为proguard。我认为它被称为“缩小”,这允许proguard运行。话虽如此,这些指令仅适用于Eclipse。 - user2676468
由于某些原因,我仍然在我的类中看到Log调用。 - IgorGanapolsky
我发现日志调用仅在发布版本中被删除。 - Yazazzello

10
如果你有Android Studio,你需要修改主应用程序的build.gradle文件。 在你的gradle文件中,你需要指定使用proguard-android-optimize.txt作为默认文件。
在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时,才不需要它,因此您可以关闭它以稍微减少处理时间。 - Yazazzello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接