Android Proguard Release导致不执行for-loop
Android Proguard Release causes not executing for-loop
在我的 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
...
}
"Step 1" 日志打印正确,objectList.size() > 0
。我不明白是什么导致 "Step 2" 从未打印日志(并且从未执行过 for 循环中的所有代码)。我正在使用 Android 设备管理器 Logcat。
在调试模式下或禁用 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 会导致一个罕见的问题,一个特定的 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
...
}
"Step 1" 日志打印正确,objectList.size() > 0
。我不明白是什么导致 "Step 2" 从未打印日志(并且从未执行过 for 循环中的所有代码)。我正在使用 Android 设备管理器 Logcat。
在调试模式下或禁用 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.