android - 从 Backstack 添加 Fragment 时出现 IllegalStateException

标签 android android-fragments android-dialogfragment illegalstateexception fragment-backstack

我不时收到以下崩溃报告:

java.lang.IllegalStateException: 
  at androidx.fragment.app.FragmentManagerImpl.addFragment (FragmentManagerImpl.java:1916)
  at androidx.fragment.app.BackStackRecord.executePopOps (BackStackRecord.java:828)
  at androidx.fragment.app.FragmentManagerImpl.executeOps (FragmentManagerImpl.java:2622)
  at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether (FragmentManagerImpl.java:2411)
  at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute (FragmentManagerImpl.java:2366)
  at androidx.fragment.app.FragmentManagerImpl.execPendingActions (FragmentManagerImpl.java:2273)
  at androidx.fragment.app.FragmentManagerImpl$1.run (FragmentManagerImpl.java:733)
  at android.os.Handler.handleCallback (Handler.java:808)
  at android.os.Handler.dispatchMessage (Handler.java:101)
  at android.os.Looper.loop (Looper.java:166)
  at android.app.ActivityThread.main (ActivityThread.java:7529)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:245)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:921)

在 FragmentManagerImpl 的第 1916 行我可以找到:

throw new IllegalStateException("Fragment already added: " + fragment);

所以它说已经添加了一些 fragment 。不幸的是,Google 不再在 Google Play Console 中显示该消息(已添加哪个 fragment )。据我了解 Stacktrace,当从后台堆栈添加 fragment 时会发生此异常,对吗?

我有一个FrameLayout,我可以在其中添加/删除 fragment 。我总是用以下代码添加它们:

public void addFragment(FragmentActivity activity, Fragment fragment) {
    FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
    String tag = fragment.getClass().getCanonicalName();
    Fragment prev = activity.getSupportFragmentManager().findFragmentByTag(tag);
    if (fragment.isAdded()) {
        return;
    }
    if (prev != null) {
        transaction.remove(prev);
    }
    transaction.replace(R.id.fragment_container, fragment, tag);
    transaction.addToBackStack(null);
    transaction.commit();

我使用以下方法添加 DialogFragments:

public void openFragmentDialog(FragmentActivity activity, DialogFragment dialogFragment, String tag) {
    FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
    Fragment prev = activity.getSupportFragmentManager().findFragmentByTag(tag);
    if (prev != null) {
        transaction.remove(prev);
    }
    transaction.addToBackStack(null);
    dialogFragment.show(transaction, tag);
}

什么情况下会发生IllegalStateException?我添加/替换 Fragments/DialogFragments 的方式是否错误?我永远无法重现该错误。但我收到了来自 Android 4.4 - Android 9 和所有类型设备的报告,但我不知道它会在哪里发生。

可能是动画或设备速度慢的原因吗?因为这种情况只是偶尔发生。

最佳答案

请注意,您正在添加和删除具有相同标签的两个不同 fragment - 那么标签也应该不同。如果 prev fragment 是不同类的实例,为什么要使用 fragment 的类名作为标记来查找它?

您应该添加一个 if 语句来检查 prevfragment 有时是否不是同一实例(因为标签相同)。

如果两个 fragment 是同一个实例,并且您仍然想要删除然后添加相同的 fragment - 您可能必须在两个不同的事务中执行此操作,以防止“fragment 已添加” 异常.

关于android - 从 Backstack 添加 Fragment 时出现 IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56973487/

相关文章:

android: 查看进程的cpu使用情况

android - 如何使用Xamarin在android上找到当前显示的 fragment

安卓 fragment 。在屏幕旋转或配置更改期间保留 AsyncTask

android - 如何获取 DialogFragment 附带的对话框? [安卓]

java - 具有不同功能的多个 DialogFragments

android - 由于 Manage_External_Storage,应用程序在 Play 商店中被拒绝,即使我的应用程序不使用此权限

java - 实现 canvas.drawBitmap 方法时如何避免内存泄漏?

android - 使用 BLE 的室内导航和跟踪人员

android - java.lang.IllegalStateException(在onSaveInstanceState之后不能执行这个 Action )

android - 在android中将数据从activity传递到dialogFragment