微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SupportFragmentManager被破坏,在幕后

如何解决SupportFragmentManager被破坏,在幕后

我的MainActivity上有这种情况:

 // onCreate
firebaseAuth.addAuthStateListener { firebaseAuth ->
            when (firebaseAuth.currentUser) {
                null -> {
                    hideAppBars()
                    clearBackStack(supportFragmentManager)
                    showFragment(fragment = LoginorRegisterFragment())
                }
                else -> {
                    showAppBars()
                    clearBackStack(supportFragmentManager)
                    showFragment(fragment = HomeFragment())
                }
            }
        }

clearBastack只是从片段的整个后栈弹出的一种方法

private fun clearBackStack(fragmentManager: FragmentManager) {
        with(fragmentManager) {
            if (backStackEntryCount > 0)
                popBackStack()
        }
    }

showFragment方法

fun showFragment(fragment: Fragment,addToBackStack: Boolean = false) {
            supportFragmentManager.beginTransaction().apply {
                replace(R.id.fragmentContainer,fragment)
                if (addToBackStack) addToBackStack(null)
            }.commit()
    }

在通常的流程中,一切正常。点击登录:BackStack清除,从LoginFragment进入HomeFragment。但是,如果我进入LoginFragment后按回去并继续,则会得到IllegalStateException: FragmentManager has been destroyed

似乎可以解决此问题的

明确检查if(!supportFragmentManager.isDestroyed)

fun showFragment(fragment: Fragment,addToBackStack: Boolean = false) {
        if (!supportFragmentManager.isDestroyed) {
            supportFragmentManager.beginTransaction().apply {
                replace(R.id.fragmentContainer,fragment)
                if (addToBackStack) addToBackStack(null)
            }.commit()
        }
    }

更新:完整堆栈跟踪:

java.lang.IllegalStateException: FragmentManager has been destroyed
        at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:1725)
        at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:321)
        at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:286)
        at com.coroutinedispatcher.datacrypt.MainActivity.showFragment(MainActivity.kt:57)
        at com.coroutinedispatcher.datacrypt.MainActivity.showFragment$default(MainActivity.kt:52)
        at com.coroutinedispatcher.datacrypt.MainActivity$onCreate$1.onAuthStateChanged(MainActivity.kt:36)
        at com.google.firebase.auth.zzj.run(com.google.firebase:firebase-auth@@19.4.0:3)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at com.google.android.gms.internal.firebase_auth.zzj.dispatchMessage(com.google.firebase:firebase-auth@@19.4.0:6)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

引发的行是supportFragmentManager.apply{bla()}.commit()

问题是,为什么,后台实际上发生了什么?

解决方法

您应在Activity的onDestroy中删除AuthStateListnener。

 // onCreate
private val authStateListener = AuthStateListener { firebaseAuth ->
            when (firebaseAuth.currentUser) {
                null -> {
                    hideAppBars()
                    clearBackStack(supportFragmentManager)
                    showFragment(fragment = LoginOrRegisterFragment())
                }
                else -> {
                    showAppBars()
                    clearBackStack(supportFragmentManager)
                    showFragment(fragment = HomeFragment())
                }
            }
        }

override fun onCreate(...) {
    super.onCreate(...)
    firebaseAuth.addAuthStateListener(authStateListener)
}


override fun onDestroy() {
    firebaseAuth.removeAuthStateListener(authStateListener)
    super.onDestroy()
}

尽管从技术上讲,您还应该考虑到这仍可能在onStop之后触发片段事务,这将导致this action cannot be performed after onSaveInstanceState错误,因此实际上您应该仅在Activity至少已启动时才处理导航操作

例如,您可以使用https://github.com/Zhuinden/live-event

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。