【问题标题】:Android Proguard Release causes not executing for-loopAndroid Proguard Release 导致不执行 for-loop
【发布时间】:2015-05-14 03:03:53
【问题描述】:

在我的 Android 应用程序中,我正在发布模式下构建。激活 Proguard 会导致一个罕见的问题,永远不会执行特定的 for 循环:

List<MyClass> objectList = getObjectList();
Log.d("Step 1", String.valueOf(objectList.size())); //Print size > 0

for(MyClass object: objectList) {
  Log.d("Step 2", object.toString()); //Never printed
  ...
}

“步骤 1”日志打印正确,objectList.size() &gt; 0。我不明白是什么原因导致“步骤 2”日志永远不会打印(并且所有进入 for 循环的代码都不会执行)。我正在使用 Android 设备管理器 Logcat。

在调试模式或禁用 Proguard 时,此 sn-p 可以正常工作。

提前致谢。

更新

我刚刚添加了-dontoptimize,但问题没有解决。这是我的 proguard-rules 文件:

-dontoptimize
-dontpreverify
-repackageclasses ''
-allowaccessmodification
#-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*,EnclosingMethod,SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile

-keepnames class com.androidplot.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class org.acra.** { *; }
-keep,allowoptimization class com.mypackage.myapp.model.** { *; }

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.preference.PreferenceFragment

-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * implements android.os.Parcelable {
    static android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

-dontwarn com.mypackage.myapp.**
-dontwarn com.fasterxml.jackson.databind.ext.**
-dontwarn com.google.common.**
-dontwarn android.support.**

【问题讨论】:

  • 可能你的toString 返回 null 或空字符串,在这种情况下它不会被记录
  • 不,这些情况已经过验证,而且 toString() 在 MyClass 中是 @Override 并且总是打印一个字符串。
  • 您是否尝试记录其他内容以确保没有发生这种情况?
  • 是的,而且for循环包含更多代码,不仅仅是Log.d指令。
  • 下一步是反编译混淆后的代码,以查看 proguard 运行后究竟执行了什么。

标签: android for-loop proguard


【解决方案1】:

https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/troubleshooting.html

消失的循环

如果您的代码包含空的忙等待循环, ProGuard 的优化步骤可能会删除它们。更具体地说,这 如果循环不断检查非易失性的值,则会发生 在不同线程中更改的字段。的规格 Java 虚拟机要求您始终标记以下字段 跨不同线程访问,无需进一步同步 易挥发的。如果由于某种原因这是不可能的,你将不得不 使用 -dontoptimize 选项关闭优化。

【讨论】:

  • 感谢@Terence,我在proguard 规则文件中添加了-dontoptimize,但问题仍然存在。我只是用 proguard 规则文件内容更新问题。
  • 我不知道 proguard 能够判断出Log.d 没有做任何有用的事情。它确实会写入应用程序之外的流,所以我认为 proguard 没有资格认为它没用。
  • 您在代码中使用的是 Jackson 还是 Gson?必须防止您的特定于 Json 数据的类被混淆。
  • 我在 proguard 规则文件中使用 -keepattributes *Annotation*-keepnames class com.fasterxml.jackson.** { *; }。是否足以防止杰克逊课程中的混淆?问题仍然存在,我不得不在没有 proguard 的情况下发布......这是一场噩梦!!!
  • 是的@squeeish,我重写了代码。我从来没有找到错误原因。
猜你喜欢
  • 2020-10-29
  • 2019-08-02
  • 2015-04-19
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 2018-10-26
  • 1970-01-01
相关资源
最近更新 更多