如何修复 FragmentManager 已经在 FragmentTransaction 中执行事务?

Mr.*_*aks 6 android android-fragments android-activity google-cloud-firestore

我遇到了麻烦FragmentManager is already executing transactions。我研究如何解决这个问题,但答案并不是我在代码中得到的答案。他们使用 viewpager 和片段管理器,但我使用片段事务只是因为我使用底部导航栏。

\n\n

根本原因是来自主片段的快照侦听器。有人可以帮我解决这个问题吗?这是我的代码:

\n\n
MainActivity.java\nfinal Intent intent = getIntent();\n        final String UserID = intent.getStringExtra("userid");\n\n        final HomeFragment fragment = new HomeFragment();\n        Bundle bundleh = new Bundle();\n        bundleh.putString("userid", UserID);\n        fragment.setArguments(bundleh);\n\n        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();\n        fragmentTransaction.replace(R.id.fragment_container, fragment);\n        fragmentTransaction.commitNow();\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是错误指向的行

\n\n
HomeFragment.java\ndb.collection("Baskets").document(uid).collection("Store_Baskets")\n                .addSnapshotListener(getActivity(), new EventListener<QuerySnapshot>() {\n                    @Override\n                    public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {\n                        if (e != null){\n                            Log.e(LOG_DB, e.toString());\n                        }else {\n                            List<String> ids = null;\n                            for (DocumentSnapshot ds: queryDocumentSnapshots){\n                                ids.add(ds.getId());\n                            }\n                            if (ids.size()==0){\n                                basket_count.setText("0");\n                            }else {\n                                basket_count.setText(String.valueOf(ids.size()));\n                            }\n                        }\n                    }\n                });\n
Run Code Online (Sandbox Code Playgroud)\n\n

堆栈跟踪

\n\n
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dreamakers.coonna/com.dreamakers.coonna.Activity.HomeBuyersActivity}: java.lang.IllegalStateException: FragmentManager is already executing transactions\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2534)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2608)\n        at android.app.ActivityThread.access$800(ActivityThread.java:178)\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)\n        at android.os.Handler.dispatchMessage(Handler.java:111)\n        at android.os.Looper.loop(Looper.java:194)\n        at android.app.ActivityThread.main(ActivityThread.java:5637)\n        at java.lang.reflect.Method.invoke(Native Method)\n        at java.lang.reflect.Method.invoke(Method.java:372)\n        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)\n     Caused by: java.lang.IllegalStateException: FragmentManager is already executing transactions\n        at androidx.fragment.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:2207)\n        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2267)\n        at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:814)\n        at com.google.firebase.firestore.core.ActivityScope.lambda$onFragmentActivityStopCallOnce$1(com.google.firebase:firebase-firestore@@21.1.1:180)\n        at com.google.firebase.firestore.core.ActivityScope$$Lambda$2.run(com.google.firebase:firebase-firestore@@21.1.1)\n        at android.app.Activity.runOnUiThread(Activity.java:5384)\n        at com.google.firebase.firestore.core.ActivityScope.onFragmentActivityStopCallOnce(com.google.firebase:firebase-firestore@@21.1.1:164)\n        at com.google.firebase.firestore.core.ActivityScope.bind(com.google.firebase:firebase-firestore@@21.1.1:192)\n        at com.google.firebase.firestore.Query.addSnapshotListenerInternal(com.google.firebase:firebase-firestore@@21.1.1:1035)\n        at com.google.firebase.firestore.Query.addSnapshotListener(com.google.firebase:firebase-firestore@@21.1.1:995)\n        at com.google.firebase.firestore.Query.addSnapshotListener(com.google.firebase:firebase-firestore@@21.1.1:939)\n        at com.dreamakers.coonna.Activity.HomeFragment.onCreateView(HomeFragment.java:166)\n        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439)\n        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)\n        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)\n        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)\n        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)\n        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)\n        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)\n        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)\n        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)\n        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)\n        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)\n        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)\n        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:620)\n        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)\n        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1244)\n        at android.app.Activity.performStart(Activity.java:6108)\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2491)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2608)\xc2\xa0\n        at android.app.ActivityThread.access$800(ActivityThread.java:178)\xc2\xa0\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)\xc2\xa0\n        at android.os.Handler.dispatchMessage(Handler.java:111)\xc2\xa0\n        at android.os.Looper.loop(Looper.java:194)\xc2\xa0\n        at android.app.ActivityThread.main(ActivityThread.java:5637)\xc2\xa0\n        at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n        at java.lang.reflect.Method.invoke(Method.java:372)\xc2\xa0\n        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)\xc2\xa0\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n

mat*_*dev 1

您应该将 db.collection 相关代码从 HomeFragment 移至onCreate()onActivityCreated()getChildFragmentManager()在片段中使用:

FragmentTransaction fragmentTransaction = 
fragment.getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)

另外,你应该使用fragmentTransaction.commit();而不是fragmentTransaction.commitNow();

来自 Javadoc:

使用提交的事务commitNow()可能不会添加到 FragmentManager 的返回堆栈中

commitNow()事务只能在其包含的活动保存其状态之前提交。如果在此之后尝试提交,则会引发异常。这是因为如果活动需要从其状态恢复,则提交后的状态可能会丢失。