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

时间:2016-04-05 14:27:45

标签: java android android-fragments android-activity illegalstateexception

我想说清楚这个问题看起来与one I asked earlier非常相似,但我并没有问完全相同的问题。

在我之前的问题中,我得到了一个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) 

MainActivity (代码段)

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;
    }
}

1 个答案:

答案 0 :(得分:1)

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

GeneralSettingsFragment尚未附加到Activity,因此它没有主机。这会抛出您尝试提交IllegalStateException("Activity has been destroyed")时看到的FragmentTransaction异常。

目前还不清楚为什么当你已经在一个新实例中时,你正在创建一个新的GeneralSettingsVariableFragment

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