【问题标题】:How to fix FragmentManager is already executing transactions in FragmentTransaction?如何修复 FragmentManager 已经在 FragmentTransaction 中执行事务?
【发布时间】:2020-02-11 21:58:44
【问题描述】:

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

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

MainActivity.java
final Intent intent = getIntent();
        final String UserID = intent.getStringExtra("userid");

        final HomeFragment fragment = new HomeFragment();
        Bundle bundleh = new Bundle();
        bundleh.putString("userid", UserID);
        fragment.setArguments(bundleh);

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container, fragment);
        fragmentTransaction.commitNow();

这是错误指向的行

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

堆栈跟踪

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

【问题讨论】:

    标签: android android-fragments android-activity google-cloud-firestore


    【解决方案1】:

    您应该将 db.collection 相关代码从 HomeFragment 的 onCreate() 移动到 onActivityCreated(),并在片段中使用 getChildFragmentManager()

    FragmentTransaction fragmentTransaction = 
    fragment.getChildFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
    

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

    来自 Javadoc:

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

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

    【讨论】:

    • 我只是将其更改为commit(),但我的应用程序仍然崩溃
    • 请发布崩溃的堆栈跟踪
    • 什么是 mPagerAdapter 先生?
    • 我已经更新了我的问题并发布了堆栈跟踪先生。请看一看。
    • 调用fragment.getChildFragmentManager()
    【解决方案2】:

    如果您正在使用 firebase 并且您正在侦听此类文档的更改

         docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
    
                //Doing work
            }
        });
    

    更新您的代码以使用 ListenerRegistration 代替

      ListenerRegistration registration = docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
    
            }
        });
    

    完成后将其删除

       @Override
    public void onStop() {
        super.onStop();
        registration.remove();
    }
    

    【讨论】:

    • 在从另一个片段开始片段时也使用 getChildFragmentManager()。
    • 是的,我正在这样做,但即使我使用它,我仍然会收到错误消息。在 getChildFragment() 上,我无法使用它,因为它无法解析,但是当我在 getChildFragmentManager() 之前添加片段时,它可以解决它,但是我又遇到了一个错误,片段尚未附加。
    • 只有在另一个片段中时才应该调用 getChildFragmentManager。您是否还更改了代码以使用 ListenerRegistration?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    相关资源
    最近更新 更多