Support Fragment + TabWidget + Samsung Device = & ldquo; Java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState & rdquo;

advertisements

I have a very simple FragmentActivity which using android.support.v4 library, there are only a TabHost inside the FragmentActivity, which contain 4 fragment.

No async task, no implementation of onSaveInstanceState().

After few week on the market I got lot of exception report called "java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState" (see stack trace on below), all from Samsung device(SM-N9003, GT-I9305, GT-N7100...etc.), totally no ideas what's going wrong.

I have searched some similar question before, but no answer at all.

Layout :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0" />
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>

Code :

private void setupTabs() {
    FragmentTabHost tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
    tabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

    tabHost.addTab(setIndicator(this, tabHost.newTabSpec(FragmentList), getString(R.string.tabwidget_List), R.drawable.btn_icon_order), ListFragment.class, null);
    tabHost.addTab(setIndicator(this, tabHost.newTabSpec(FragmentSwitch), getString(R.string.tabwidget_Switch), R.drawable.btn_icon_switch), SwitchFragment.class, null);
    tabHost.addTab(setIndicator(this, tabHost.newTabSpec(FragmentQueue), getString(R.string.tabwidget_Queue), R.drawable.btn_icon_queue), QueueFragment.class, null);
    tabHost.addTab(setIndicator(this, tabHost.newTabSpec(FragmentMore), getString(R.string.tabwidget_More), R.drawable.btn_icon_more), MoreFragment.class, null);

}

private TabSpec setIndicator(Context context, TabSpec tabSpec, String Title,int resId) {
    View view = LayoutInflater.from(context).inflate(R.layout.tab_widget, null);

    ImageView ivTTIcon = (ImageView) view.findViewById(R.id.ivTTIcon);
    ivTTIcon.setImageResource(resId);

    TextView tvTTText = (TextView) view.findViewById(R.id.tvTTText);
    tvTTText.setText(Title);

    return tabSpec.setIndicator(view);
}

Stack trace :

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1343)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1354)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
at android.support.v4.app.FragmentTabHost.onTabChanged(FragmentTabHost.java:309)
at android.widget.TabHost.invokeOnTabChangeListener(TabHost.java:463)
at android.widget.TabHost.setCurrentTab(TabHost.java:448) at android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:161)
at android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:563)
at android.view.View.performClick(View.java:4475) at android.view.View$PerformClick.run(View.java:18784) at android.os.Handler.handleCallback(Handler.java:730) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5414) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
at dalvik.system.NativeStart.main(Native Method)


Here is the solution,

This problem occurs if tab selection action performs after onSaveInstanceState get called. One example like, if user selects and holds any tab and at the same time also selects the Home Button.

To solve this issue just call mTabHost.getTabWidget().setEnabled(false); under onPause of the Fragment/Activity and call mTabHost.getTabWidget().setEnabled(true); under onResume.