屏幕关闭时DialogFragment IllegalStateException

时间:2019-01-07 23:07:41

标签: android android-fragments android-dialogfragment illegalstateexception

首先,我阅读了数十个SO问题,并阅读了Alex Lockwood的精彩文章,内容涉及与片段事务有关的IllegalStateException问题:https://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html- tl; dr完成我的作业

但是我什么都没发现是IllegalStateException问题,当屏幕关闭并且我们正在尝试执行片段事务时-在我的情况下显示DialogFragment

我的应用程序中发生的实际情况是对其他活动结果做出了反应,后来又显示了DialogFragment正如许多SO用户所建议的那样,我不是显示onActivityResult的对话,而是显示onPostResume的对话(我也尝试过使用onResumeFragments这个

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    Timber.i("${this::class.java.simpleName} onActivityResult")
    activityResult = ActivityResult(this::class, requestCode, resultCode, data)
}

override fun onPostResume() {
    super.onPostResume()
    Timber.i("${this::class.java.simpleName} onPostResume")
    activityResult?.let { ActivityResultRepository.resultsSubject.onNext(it) }
}

override fun onResumeFragments() {
    super.onResumeFragments()
    Timber.i("${this::class.java.simpleName} onResumeFragments")
}

我无法在设备(Mate 20 pro)或仿真器上重现异常,但是我收到来自应用程序用户的崩溃报告(受影响的用户为0.5%)

我的假设是,我的应用程序试图在屏幕关闭后显示对话框。屏幕关闭是一个任意事件,它导致调用onSaveInstanceState方法,并且可以在我的onPostResume方法之前调用它。 但这只是我的假设!,也许还有另一个导致异常的原因

有人遇到过类似的问题并设法解决吗?我知道我可以使用commitAllowingStateLoss,但首先-show的{​​{1}}方法不允许这样做,必须使用DialogFragment手动显示对话框(不要知道是否有任何暗示),其次FragmentManager通常是一件坏事

我正在添加崩溃报告,尽管每个人都已经看到它了:)

commitAllowingStateLoss

3 个答案:

答案 0 :(得分:0)

活动类具有方法isFinishing()link to method。您可以轻松检查:

if (!this.isFinishing)
    loadingDialog.show()

上面的示例打开了纯对话框,但是您可以将其与DialogFragment一起使用。

答案 1 :(得分:0)

这种情况经常发生。活动状态不正确,无法显示对话框。您可以通过以下方法来保护自己:

if (!isFinishing() && !isDestroyed()) {
    dialog.show();
}

答案 2 :(得分:0)

我已经接受@MatPag答案,但我最终得到了不同的解决方案,所以我要发布它,也许会对某人有所帮助

在我的情况下,我不在乎saveInstanceState-在Android重新创建活动时显示活动的初始状态对我来说是完全可以的,因此我将null传递给父onCreate方法:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(null) 
}

稍后,当显示对话框时,我捕获了可能抛出的IllegalStateException,为此我创建了辅助方法:

private fun DialogFragment.showAllowingStateLoss(manager: FragmentManager?, tag: String) {
    try {
        this.show(manager, tag)
    } catch (e: IllegalStateException) {
        // no-op
    }
}