片段计数无法按预期使用 ProGuard
Fragment count not working as expected with ProGuard
我的 AppCompatActivity 上有一个函数,它确定片段列表中的片段数量 - 下面是代码:
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();
}
代码在调试时运行良好,即 ProGuard 关闭。但是当导出已签名的 APK 时,它没有按预期工作,即它没有达到 hideActionBar
。当我回到初始屏幕时,我可以看到 hideActionBar()
没有被调用。我需要再次在操作栏中单击返回,然后它会隐藏操作栏。任何提示可能是什么原因造成的?
我的 ProGuard 文件中是否缺少我需要添加的内容?
附加的 ProGuard 文件:
# 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(...);
}
这是使用 Proguard
和 class 名称的预期行为。
您正在做:
fragment.getClass().getSimpleName().equals("MyFragmentClassName")
但是MyFragmentClassName
是用Proguard
改的,所以要解析原来的class名字就得保留。
最优化的版本是只保留需要它的 classes 的名字。
在这种特定情况下,您必须添加到 Proguard
文件:
-keepnames package.of.this.fragment.SelfCBaseFragment
-keepnames package.of.this.other.fragment.ABCFragment
可能解决此问题的更好方法是用 classes 的混淆名称替换硬编码字符串。例如:
fragment.getClass().getName().equals(SelfCBaseFragment.class.getName())
这样您仍然可以混淆 SelfCBaseFragment
class 的名称,因为 fragment.getClass().getName()
将返回与 SelfCBaseFragment.class.getName()
.
相同的名称
我的 AppCompatActivity 上有一个函数,它确定片段列表中的片段数量 - 下面是代码:
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();
}
代码在调试时运行良好,即 ProGuard 关闭。但是当导出已签名的 APK 时,它没有按预期工作,即它没有达到 hideActionBar
。当我回到初始屏幕时,我可以看到 hideActionBar()
没有被调用。我需要再次在操作栏中单击返回,然后它会隐藏操作栏。任何提示可能是什么原因造成的?
我的 ProGuard 文件中是否缺少我需要添加的内容?
附加的 ProGuard 文件:
# 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(...);
}
这是使用 Proguard
和 class 名称的预期行为。
您正在做:
fragment.getClass().getSimpleName().equals("MyFragmentClassName")
但是MyFragmentClassName
是用Proguard
改的,所以要解析原来的class名字就得保留。
最优化的版本是只保留需要它的 classes 的名字。
在这种特定情况下,您必须添加到 Proguard
文件:
-keepnames package.of.this.fragment.SelfCBaseFragment
-keepnames package.of.this.other.fragment.ABCFragment
可能解决此问题的更好方法是用 classes 的混淆名称替换硬编码字符串。例如:
fragment.getClass().getName().equals(SelfCBaseFragment.class.getName())
这样您仍然可以混淆 SelfCBaseFragment
class 的名称,因为 fragment.getClass().getName()
将返回与 SelfCBaseFragment.class.getName()
.