【问题标题】:Android - Transaction Commit failedAndroid - 事务提交失败
【发布时间】:2020-06-23 15:02:17
【问题描述】:

您好,我是 Android 领域的新手,

我在使用 FragmentTransaction 更改 Fragment 时遇到问题,代码有什么问题? 据我所知,提交是问题所在,因为它被调用了两次,但似乎不可能,而且我在调试器中看不到这种行为。

package com.example.foodgent.Logic;

import android.annotation.SuppressLint;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;

import com.example.foodgent.UserInterface.Fragment2;
import com.example.foodgent.UserInterface.Fragment3;
import com.example.foodgent.UserInterface.MainActivity;
import com.example.fragment.R;

public class FragmentChanger<mainActivity>  extends AppCompatActivity {

    private Button btnNavFrag1;
    private Button btnNavFrag2;
    private Button btnNavFrag3;
    private MainActivity mainActivity;
    private int currentPage;
    public FragmentChanger(Button btnNavFrag1, Button btnNavFrag2, Button btnNavFrag3, MainActivity activity) {
        this.btnNavFrag1 = btnNavFrag1;
        this.btnNavFrag2 = btnNavFrag2;
        this.btnNavFrag3 = btnNavFrag3;
        this.mainActivity= mainActivity;
        currentPage=0;
    }



    @SuppressLint("RestrictedApi")
    public void change(int number, ViewPager viewPager){

   final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    switch (number) {
            case 0:
                if (currentPage != 0) {
                    btnNavFrag1.setBackgroundResource(R.drawable.fragment_active_button);
                    btnNavFrag2.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag3.setBackgroundResource(R.drawable.fragment_buttons);

                    // Replace whatever is in the fragment_container view with this fragment,
                    // and add the transaction to the back stack if needed
                    transaction.replace(R.id.fragment, new Fragment());

                    transaction.addToBackStack(null);
                    transaction.commit();
                }
                break;

            case 1:
                if (currentPage != 1) {
                    btnNavFrag1.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag2.setBackgroundResource(R.drawable.fragment_active_button);
                    btnNavFrag3.setBackgroundResource(R.drawable.fragment_buttons);

                    // Replace whatever is in the fragment_container view with this fragment,
                    // and add the transaction to the back stack if needed
                    transaction.replace(R.id.fragment, new Fragment2());

                    transaction.addToBackStack(null);
                    transaction.commit();
                }
                break;
            case 2:

                if (currentPage != 2) {
                    btnNavFrag1.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag2.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag3.setBackgroundResource(R.drawable.fragment_active_button);


                    // Replace whatever is in the fragment_container view with this fragment,
                    // and add the transaction to the back stack if needed
                    transaction.replace(R.id.fragment, new Fragment3());

                    transaction.addToBackStack(null);
                    transaction.commit();
                    }

                break;

        }

        currentPage=number;
        //set the new Page
        viewPager.setCurrentItem(number);
    }

    public int getCurrentPage(){
        return currentPage;
    }
}

错误:

AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.fragment, PID: 24603
    java.lang.IllegalStateException: Activity has been destroyed
        at androidx.fragment.app.FragmentManagerImpl.enqueueAction(FragmentManagerImpl.java:1566)
        at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:317)
        at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:282)
        at com.example.foodgent.Logic.FragmentChanger.change(FragmentChanger.java:82)
        at com.example.foodgent.UserInterface.MainActivity.setViewPager(MainActivity.java:111)
        at com.example.foodgent.UserInterface.MainActivity$6.onClick(MainActivity.java:366)
        at android.view.View.performClick(View.java:6669)
        at android.view.View.performClickInternal(View.java:6638)
        at android.view.View.access$3100(View.java:789)
        at android.view.View$PerformClick.run(View.java:26145)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6898)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
W/OPDiagnose: getService:OPDiagnoseService NULL
D/OSTracker: OS Event: crash
I/Process: Sending signal. PID: 24603 SIG: 9
Process 24603 terminated.

片段类:

package com.example.foodgent.UserInterface;


import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.example.fragment.R;


public class Fragment1 extends Fragment {

    private static final String TAG = "Fragment1";

    private Button btnNavFrag1;
    private Button btnNavFrag2;
    private Button btnNavFrag3;
    private Button btnNavSecondActivity;
    Activity mainActivity;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment1_layout, container, false);


            return view;

    }
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (activity != null) {
            try {
                mainActivity = activity;
            }
            catch (ClassCastException e) {
                Log.v(TAG, "Exception: " + e.getLocalizedMessage());
            }
        }
    }
}

【问题讨论】:

  • FragmentChanger 类显然没有用作Activity,因此不应扩展任何Activity 类。从类声明中删除extends AppCompatActivity,您将看到问题的根源在哪里;即getSupportFragmentManager() 电话。

标签: android transactions fragment commit


【解决方案1】:

我删除了 Fragment Changer 类并更改了 Mainactivity 中的 Fragment

问题是transaction.commit(),由于我不能在FragmentChanger中多次调用它,按下Tab按钮后出现错误。

【讨论】:

  • 不,问题是您自己直接实例化了 Activity 类。你不能这样做,并让它正常工作。系统必须处理Activity 实例化;否则它没有正确初始化,你会在你的堆栈跟踪中得到类似的错误。您仍然可以使用您的 FragmentChanger 助手,但您需要使用您在构造函数中传递的 MainActivity 来处理需要 Activity 的任何内容,例如 getSupportFragmentManager() 调用。仅供参考。
  • 谢谢你试试看!在 mainactivty 中拥有如此多的内容会使整合内容变得越来越困难!
【解决方案2】:

如果错误发生在 transaction.commit() 时?然后您可以通过检查活动是否未完成来将调用包含在内。

if (!this.isFinishing()){
        transaction.commit();
}

【讨论】:

    【解决方案3】:

    您是否引用了该片段中的活动?尝试在 Fragment 的onAttach 中保存/更新活动:

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        if (activity != null) {
            try {
                mainActivity = activity;
            }
            catch (ClassCastException e) {
                Log.v(TAG, "Exception: " + e.getLocalizedMessage());
            }
        }
    }
    

    Android 会在设备旋转时保存、销毁和重新创建您的 Activity 和 Fragments,它可能会重用您的 Fragment,这些片段包含对已销毁 Activity 的引用。

    在 onAttach 中保存对新活动的引用将更新该引用。

    【讨论】:

    • 好的,我在我的 Fragment 类中给出了这段代码,问题是 mainActivity 始终为空,所以我缺少什么部分? (将在下一分钟添加代码)
    猜你喜欢
    • 2015-10-25
    • 2023-03-11
    • 2016-02-13
    • 2019-10-09
    • 2013-04-11
    • 2017-11-18
    • 2018-12-13
    • 2012-01-02
    • 2013-09-17
    相关资源
    最近更新 更多