在我的 Android 应用程序中,我正在以 Release模式构建。激活 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() > 0
。我不明白是什么导致“第 2 步”日志从未打印(并且所有进入 for 循环的代码从未执行)。我正在使用 Android 设备管理器 Logcat。
在 Debug模式下或 Proguard 禁用时,此代码段可以正常工作。
提前致谢。
更新
我刚刚添加了-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.**
最佳答案
Disappearing loops
If your code contains empty busy-waiting loops, ProGuard's optimization step may remove them. More specifically, this happens if a loop continuously checks the value of a non-volatile field that is changed in a different thread. The specifications of the Java Virtual Machine require that you always mark fields that are accessed across different threads without further synchronization as volatile. If this is not possible for some reason, you'll have to switch off optimization using the -dontoptimize option.
关于Android Proguard Release导致不执行for-loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30204758/