Search code examples
androidandroid-fragmentsproguardandroid-proguardfragment-backstack

Fragment count not working as expected with ProGuard


I have a function on my AppCompatActivity where it determines the number of fragments in the fragment list - below is the code :

if (getSupportFragmentManager().getBackStackEntryCount() > 0) {

            List<Fragment> fragmentList = getSupportFragmentManager().getFragments();

            if (fragmentList != null) {
                for (Fragment fragment : fragmentList) {
                    if (fragment != null) {
                        if (fragment.getClass().getSimpleName().equals("SelfCBaseFragment")) {

                            if (fragment.getChildFragmentManager().getBackStackEntryCount() > 1) {
                                fragment.getChildFragmentManager().popBackStack();

                            } else {
                                getSupportFragmentManager().popBackStack();
                                hideActionBar();
                            }
                        } else if (fragment.getClass().getSimpleName().equals("ABCFragment")) {

                            getSupportFragmentManager().popBackStackImmediate();
                        } else {
                            MyLog.d("FragmentName:", fragment.getClass().getSimpleName());
                            getSupportFragmentManager().popBackStack();
                        }
                    }

                }
            }
        } else {
            hideActionBar();
        }

The code works perfectly when debugging i.e ProGuard is off. But when exporting the signed APK it's not working as expected, i.e., it does not hit hideActionBar. When I am back to the initial screen, I can see it's the hideActionBar() not called. I need to click back in the action bar again and then it hides the action bar. Any hint what might be causing this?

Is there something i need to add in my ProGuard file that's missing?

ProGuard file attached :

# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


## Square Picasso specific rules ##
## https://square.github.io/picasso/ ##

-dontwarn com.squareup.okhttp.**
#json
# gson
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes Exceptions

# Gson specific classes
-keep class sun.misc.Unsafe { *; }

-keep class com.flurry.** { *; }
-dontwarn com.flurry.**
-keepattributes *Annotation*,EnclosingMethod
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-keep public class com.google.android.gms.* { public *; }
-dontwarn com.google.android.gms.**
-dontwarn android.support.**

-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }

-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}

-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

-assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);
}

Solution

  • This is the expected behavior using Proguard and class names. You are doing:

    fragment.getClass().getSimpleName().equals("MyFragmentClassName")

    But MyFragmentClassName is changed using Proguard, so you have to keep it if you want to resolve the original class name.

    The most optimized version is to keep only the names of the classes that need it. In this specific case you have to add to your Proguard file:

    -keepnames package.of.this.fragment.SelfCBaseFragment
    -keepnames package.of.this.other.fragment.ABCFragment