Android Proguard发布导致不执行for循环 [英] Android Proguard Release causes not executing for-loop

查看:135
本文介绍了Android Proguard发布导致不执行for循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  List< MyClass> objectList = getObjectList(); 
Log.d(Step 1,String.valueOf(objectList.size())); //打印尺寸> (MyClass object:objectList){
Log.d(Step 2,object.toString()); 0

//从不打印
...
}

Step 1日志打印正确, objectList.size()> 0 。我不明白是什么导致第二步从未打印日志(并且所有代码都不执行for循环)。



在调试模式或禁用Proguard的情况下,这段代码能够正常工作。 >提前致谢

更新



c> -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类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。**


解决方案

https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/troubleshooting.html如果您的代码包含空的busy->


消失的循环等待循环,
ProGuard的优化步骤可能会将其删除。更具体地说,如果循环连续检查在不同线程中更改的非易失性
字段的值,则会发生

Java虚拟机的规范要求您总是将不同线程中
访问的字段标记为
volatile。如果由于某种原因无法执行此操作,则必须使用-dontoptimize选项关闭优化


In my Android app I am building in release mode. With Proguard activated an rare issue is caused, a specific for-loop never is executed:

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
  ...
}

The "Step 1" Log is printed correctly and objectList.size() > 0. I don't understand what is causing "Step 2" Log is never printed (and all code into for-loop never executed). I am using the Android Device manager Logcat.

In debug mode or with Proguard disabled this snippet works correctly.

Thanks in advance.

Update

I just added -dontoptimize but the problem was not resolved. This is my proguard-rules file:

-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.**

解决方案

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

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循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆