为什么我的 Activity 在添加片段 (#2) 时被销毁?

Why does my Activity get destroyed upon adding a fragment (#2)?

我想说明一下,这个问题看起来与 非常相似,但我问的并不是完全相同的问题。

在我之前的问题中,我得到了一个 RuntimeException/IllegalStateException,它告诉我我的 Activity 在添加新片段时被销毁了。

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tim.timapp
    /com.example.tim.timapp.MainActivity}: java.lang.IllegalStateException: 
    Activity has been destroyed

在那种情况下,事实证明这与我以无效方式创建 MainActivity 的新实例有关:
MainActivity ma = new MainActivity();
(PSA:不要执行上述操作,而是使用 MainActivity ma = (MainActivity) getActivity();。)

我现在已经在我的整个项目中更正了这个问题,并且得到了几乎完全相同的错误。让我说清楚:我(认为我)知道原来的错误已修复,因为我在这两个 RE 之间得到了一个不同的错误,我能够自己修复它。

重申我的胡言乱语:得到第一个 RE,用我的问题的答案修复它,得到一个不同的错误,自己修复,得到 几乎 完全相同的 RE .

我搜索了我的整个项目,看看是否有与我之前犯的错误类似的东西,但我找不到任何东西,所以我来了。所以基本上,我在上一个问题上得到的答案暂时解决了我的问题。但是,这个答案对我遇到的这个新错误没有帮助,这就是我问这个问题的原因。

TL;DR: Q1 的回答首先解决了我的问题(这使它成为一个有效的答案),但它 不是 解决我现在遇到的问题,几乎 是一样的。

实际问题

所以,现在我们已经解决了这个问题,让我们继续解决我的问题。所以,我得到一个 RuntimeException/IllegalStateExcetion:

java.lang.RuntimeException: Unable to start activity  
    ComponentInfo{com.example.tim.timapp/com.example.tim.timapp.MainActivity}:  
    java.lang.IllegalStateException: Activity has been destroyed

(PS。这只是一个 RE,因为我让我的应用程序在启动时导航到 GeneralSettings 片段,以便于调试。)

我已经阅读过此类错误,但我找不到任何适用于我的项目的错误。

那么,是什么导致了这个 RuntimeException/IllegalStateException

完整日志

04-05 14:17:53.140 23411-23411/? I/art: Not late-enabling -Xcheck:jni (already on)
04-05 14:17:53.190 23411-23411/com.example.tim.timapp W/System: ClassLoader referenced unknown path: /data/app/com.example.tim.timapp-1/lib/x86_64
04-05 14:17:53.210 23411-23411/com.example.tim.timapp D/TEST DBHandler: sInstance == null
04-05 14:17:53.370 23411-23411/com.example.tim.timapp D/AndroidRuntime: Shutting down VM
04-05 14:17:53.370 23411-23411/com.example.tim.timapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.tim.timapp, PID: 23411
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tim.timapp/com.example.tim.timapp.MainActivity}: java.lang.IllegalStateException: Activity has been destroyed
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.IllegalStateException: Activity has been destroyed
        at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1433)
        at android.app.BackStackRecord.commitInternal(BackStackRecord.java:687)
        at android.app.BackStackRecord.commit(BackStackRecord.java:663)
        at com.example.tim.timapp.MainActivity.DrawVariableFragments(MainActivity.java:276)
        at com.example.fragments.Settings.GeneralSettingsFragment.onCreateView(GeneralSettingsFragment.java:58)
        at android.app.Fragment.performCreateView(Fragment.java:2220)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
        at android.app.BackStackRecord.run(BackStackRecord.java:793)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
        at android.app.FragmentController.execPendingActions(FragmentController.java:325)
        at android.app.Activity.performStart(Activity.java:6252)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
        at android.app.ActivityThread.-wrap11(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

主要内容Activity(片段)

package com.example.tim.timapp;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private static boolean isMainShown = false;
    private static boolean isSettingsShown = false;
    private static boolean doSavePopup = false;
    private static String backTitle = "";
    private String tag = "TEST MA";
    DBHandler dbHandler;

    Menu menu;

    public void DrawVariableFragments(String base,String token){
//        FragmentManager fm = getFragmentManager();
        ArrayList<String> Data;
        dbHandler = DBHandler.getInstance(this);

        int AmountOfEntries;
        int SettingsContainer;
        String SettingsTag;
        Fragment SettingsVariableFragment;
        Fragment SettingsEmptyFragment;

        if (base.equalsIgnoreCase("StuffManager")) {
            Data = new ArrayList<String>() {{add("StuffManager"); add("name"); add("tag"); }};
            SettingsContainer = R.id.FragmentContainer2;
            SettingsTag = getString(R.string.navdrawer_stuffmanager);
            SettingsVariableFragment = new StuffManagerVariableFragment();
            SettingsEmptyFragment = new StuffManagerEmptyFragment();
        } else if (base.equalsIgnoreCase("GeneralSettings")) {
            Data = new ArrayList<String>() {{add("GeneralSettings"); add("name"); add("ip"); add("port"); add("username"); add("pass"); }};
            SettingsContainer = R.id.FragmentContainerGeneralSettings;
            SettingsTag = getString(R.string.navdrawer_generalsettings);
            SettingsVariableFragment = new GeneralSettingsVariableFragment();
            SettingsEmptyFragment = new GeneralSettingsEmptyFragment();
        } else {
            Log.e(tag, "String Base not recognised");
            return;
        }
        AmountOfEntries = dbHandler.returnArray(base, Data.get(1)).size();

        FragmentManager fm = getFragmentManager().findFragmentByTag(SettingsTag).getChildFragmentManager();

        if ((dbHandler.returnArray(base, Data.get(1))).size() == 0 ) {
//            Log.d(tag, "SettingsContainer1: " + String.valueOf(SettingsContainer) + ";  SettingsEmtpyFragment1: " + SettingsEmptyFragment + ";  Base1: " + base);
            fm.beginTransaction().add(SettingsContainer, SettingsEmptyFragment, (base + "EmptyFragment")).commit();
            fm.executePendingTransactions();
            return;
        }

        if (AmountOfEntries > 0) {
            String EmptyFragName = (base + "EmptyFragment");
            if ((fm.findFragmentByTag(EmptyFragName)) != null) {
                fm.beginTransaction().remove(fm.findFragmentByTag(EmptyFragName)).commit();
                fm.executePendingTransactions();
            }
            for (int i = 0; i < AmountOfEntries; i++) {
                ArrayList<String> fragmentData = new ArrayList<>();
                for (int k=1; k < Data.size(); k++) {
                    int j=k-1;
                    fragmentData.set(j, (dbHandler.returnArray(base, Data.get(k)).get(j)));
                }

                if (token.equalsIgnoreCase("edit")) {
                    LinearLayout linearLayout = (LinearLayout) findViewById(SettingsContainer);
                    linearLayout.removeAllViews();
                    DrawVariableFragments(base ,"draw");
                } else if (token.equalsIgnoreCase("add")) {
                    if (fm.findFragmentByTag(fragmentData.get(i)) == null) {
                        fm.beginTransaction().add(SettingsContainer, SettingsVariableFragment, fragmentData.get(0)).commit();
                        fm.executePendingTransactions();
                        if (base.equalsIgnoreCase("StuffManager")) {
                            ((StuffManagerVariableFragment) fm
                                    .findFragmentByTag(fragmentData.get(i)))
                                    .setText(fragmentData.get(0), fragmentData.get(1));
                        } else if (base.equalsIgnoreCase("GeneralSettings")) {
                            ((GeneralSettingsVariableFragment) fm
                                    .findFragmentByTag(fragmentData.get(i)))
                                    .setText(fragmentData.get(0), fragmentData.get(1), fragmentData.get(2), fragmentData.get(3));
                        }
                    }
                } else if (token.equalsIgnoreCase("draw")) {
                    fm.beginTransaction().add(SettingsContainer, SettingsVariableFragment, fragmentData.get(0)).commit();
                    fm.executePendingTransactions();
                    if (base.equalsIgnoreCase("StuffManager")) {
                        ((StuffManagerVariableFragment) fm
                                .findFragmentByTag(fragmentData.get(i)))
                                .setText(fragmentData.get(0), fragmentData.get(1));
                    } else if (base.equalsIgnoreCase("GeneralSettings")) {
                        ((GeneralSettingsVariableFragment) fm
                                .findFragmentByTag(fragmentData.get(i)))
                                .setText(fragmentData.get(0), fragmentData.get(1), fragmentData.get(2), fragmentData.get(3));
                    }
                }
            }
        } else {
            Log.d("TEST", "WTF, nameArray.size != 0 && !> 0");
        }
    }
}

GeneralSettingsFragment(代码段)

package com.example.fragments.Settings;

public class GeneralSettingsFragment extends Fragment {

    MainActivity ma;
    DBHandler dbHandler;
    private static Menu optionsMenu;
    public static boolean hideDeleteAllButton = false;
    LinearLayout linearLayout;
    View rootView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_generalsettings, container, false);
        ma = (MainActivity) getActivity();
        linearLayout = (LinearLayout) rootView.findViewById(R.id.FragmentContainerGeneralSettings);

        if (linearLayout == null) {
            Log.e("GMF", "Layout is null");
        } else if (linearLayout.getChildCount() == 0) {
            GeneralSettingsInitialInputDialog GSIID = new GeneralSettingsInitialInputDialog();
            GSIID.show(getFragmentManager(), "dialog");
            hideDeleteAllButton = true;
        } else {
            hideDeleteAllButton = false;
        }
        ma.DrawVariableFragments("GeneralSettings", "draw");

        return rootView;
    }
}

您仍在以不受支持的方式做事。在 MainActivity.DrawVariableFragments() 中,您正在创建一个新的 GeneralSettingsVariableFragment(),然后对其调用 getChildFragmentManager() 并尝试提交片段。

GeneralSettingsFragment 尚未附加到 Activity,因此它没有主机。这会引发您在尝试提交 FragmentTransaction.

时看到的 IllegalStateException("Activity has been destroyed") 异常

不清楚为什么要创建一个新的 GeneralSettingsVariableFragment,而您已经在其中的一个新实例中。

要正确查找现有片段,请使用 getFragmentManager().findFragmentByTag(...)getFragmentManager().findFragmentById(...)