diff --git a/app/src/main/java/com/gh/common/fragment/FragmentManagerExt.kt b/app/src/main/java/com/gh/common/fragment/FragmentManagerExt.kt
new file mode 100644
index 0000000000..27313e54ee
--- /dev/null
+++ b/app/src/main/java/com/gh/common/fragment/FragmentManagerExt.kt
@@ -0,0 +1,74 @@
+package com.gh.common.fragment
+
+import androidx.fragment.app.FragmentManager
+import java.lang.reflect.Field
+
+fun FragmentManager.popBackStackAllowStateLoss() {
+ popBackStackAllowStateLoss(-1, 0)
+}
+
+fun FragmentManager.popBackStackAllowStateLoss(id: Int, flags: Int) {
+ if (!isStateSaved) {
+ popBackStack(id, flags)
+ } else {
+ hook { popBackStack(id, flags) }
+ }
+}
+
+fun FragmentManager.popBackStackAllowStateLoss(name: String?, flags: Int) {
+ if (!isStateSaved) {
+ popBackStack(name, flags)
+ } else {
+ hook { popBackStack(name, flags) }
+ }
+}
+
+fun FragmentManager.popBackStackImmediateAllowStateLoss() = popBackStackAllowStateLoss(-1, 0)
+
+fun FragmentManager.popBackStackImmediateAllowStateLoss(id: Int, flags: Int) =
+ if (!isStateSaved) {
+ popBackStackImmediate(id, flags)
+ } else {
+ hook { popBackStackImmediate(id, flags) }
+ }
+
+fun FragmentManager.popBackStackImmediateAllowStateLoss(name: String?, flags: Int): Boolean =
+ if (!isStateSaved) {
+ popBackStackImmediate(name, flags)
+ } else {
+ hook { popBackStackImmediate(name, flags) }
+ }
+
+/**
+ * 通过反射将FragmentManager的mStateSaved和mStopped设为false,否则Activity在回调onSavedInstance以后,
+ * 调用Fragment的popBackStack和popBackStackImmediate方法会触发“java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState”的异常。
+ * @see Sentry-418688
+ */
+private fun FragmentManager.hook(callback: FragmentManager.() -> T): T {
+ val mStateSavedField = getField(this::class.java,"mStateSaved")
+ val stateSaved = mStateSavedField.get(this);
+ mStateSavedField.set(this, false)
+ val mStoppedField = getField(this::class.java,"mStopped")
+ val stopped = mStateSavedField.get(this);
+ mStoppedField.set(this, false)
+ val result = callback.invoke(this)
+ mStateSavedField.set(this, stateSaved)
+ mStoppedField.set(this, stopped)
+ return result
+}
+
+@Throws(NoSuchFieldException::class)
+private fun getField(clazz: Class<*>, name: String): Field {
+ var cls: Class<*>? = clazz
+ while (cls != null) {
+ try {
+ val declaredField = cls.getDeclaredField(name)
+ declaredField.isAccessible = true
+ return declaredField
+ } catch (e: NoSuchFieldException) {
+ e.printStackTrace()
+ }
+ cls = cls.superclass
+ }
+ throw NoSuchFieldException()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt
index 595af14aa2..684aefa259 100644
--- a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt
@@ -15,6 +15,7 @@ import androidx.core.widget.doAfterTextChanged
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
+import com.gh.common.fragment.popBackStackAllowStateLoss
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.LogUtils
import com.gh.gamecenter.DisplayType.*
@@ -381,7 +382,7 @@ open class SearchActivity : BaseActivity() {
}
protected fun popBackToFragment(tag: String) {
- supportFragmentManager.popBackStack(tag, 0)
+ supportFragmentManager.popBackStackAllowStateLoss(tag, 0)
}
@Subscribe(threadMode = ThreadMode.MAIN)