Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.IllegalStateException: commit already called in view pager with Tablayout

Tags:

android

I am using View pager with Tablayout in my project. I am continuously getting crash report on crashlytics. Below is the stack trace.

java.lang.IllegalStateException: commit already called
   at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:624)
   at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:620)
   at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:161)
   at android.support.v4.view.ViewPager.d(ViewPager.java:1105)
   at android.support.v4.view.ViewPager.d(ViewPager.java:951)
   at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1473)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4919)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4919)
   at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1411)
   at android.widget.LinearLayout.measureVertical(LinearLayout.java:698)
   at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
   at android.view.View.measure(View.java:15635)
   at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:681)
   at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
   at android.view.View.measure(View.java:15635)
   at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:868)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4919)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4919)
   at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1411)
   at android.widget.LinearLayout.measureVertical(LinearLayout.java:698)
   at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4919)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4919)
   at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1411)
   at android.widget.LinearLayout.measureVertical(LinearLayout.java:698)
   at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4919)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2200)
   at android.view.View.measure(View.java:15635)
   at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2165)
   at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1249)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1443)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1139)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4872)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
   at android.view.Choreographer.doCallbacks(Choreographer.java:579)
   at android.view.Choreographer.doFrame(Choreographer.java:548)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
   at android.os.Handler.handleCallback(Handler.java:800)
   at android.os.Handler.dispatchMessage(Handler.java:100)
   at android.os.Looper.loop(Looper.java:194)
   at android.app.ActivityThread.main(ActivityThread.java:5371)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:525)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
   at dalvik.system.NativeStart.main(NativeStart.java)

Here is my xml file

<?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.DrawerLayout       
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/frame_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <include
                android:id="@+id/toolbar"
                layout="@layout/toolbar" />

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:background="@color/spice_laddooblue"
                app:tabMode="scrollable"
                android:layout_height="wrap_content" />

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <android.support.v4.view.ViewPager 
                    xmlns:android="http://schemas.android.com/apk/res/android"
                    android:id="@+id/pager"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                </android.support.v4.view.ViewPager>

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_share_white_24dp"
                android:layout_gravity="bottom|end"
                app:elevation="6dp"
                style="@style/floating_action_button"
                app:backgroundTint="@color/spice_laddooblue"
                app:pressedTranslationZ="12dp"/>
            </FrameLayout>


        </LinearLayout>

        <!--
              <View
            android:id="@+id/upper_view"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:visibility="visible" 
            android:layout_below = "@+id/pager"
            android:layout_above = "@+id/bannerView"/>
        -->

        <RelativeLayout
            android:id="@+id/bannerView"
            android:layout_width="match_parent"
            android:layout_height="58dp"
            android:layout_alignParentBottom="true"
            android:background="@drawable/curved_white_with_blue_border"
            android:visibility="gone">

            <TextView
                android:id="@+id/bannerText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerInParent="true"
                android:layout_centerVertical="true"
                android:gravity="center"
                android:padding="3dp"
                android:text="Banner"
                android:visibility="gone" />

            <ImageView
                android:id="@+id/bannerImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_alignParentLeft="true"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:gravity="center"
                android:padding="3dp"
                android:scaleType="fitXY"
                android:visibility="gone" />

            <ImageView
                android:id="@+id/bannerClose"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_alignParentTop="true"
                android:layout_centerVertical="true"
                android:src="@drawable/cross_icon" />
        </RelativeLayout>
    </RelativeLayout>

    <ExpandableListView
        android:id="@+id/left_drawer"
        android:layout_width="265dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#fff"
        android:choiceMode="singleChoice"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:drawSelectorOnTop="true"
        android:groupIndicator="@null"
        android:scrollbars="@null" />

</android.support.v4.widget.DrawerLayout>

Adapter code

public class TabsPagerAdapter extends FragmentStatePagerAdapter {

    Context context;
    ViewPager pager;
    int count;

    public TabsPagerAdapter(FragmentManager fm, Context context, ViewPager pager ) {
        super(fm);
        this.context = context;
        this.pager = pager;

    }
    @Override
    public CharSequence getPageTitle(int position) {
        return ActivityMain.setdynamicTabsNames.get(position);
    }

    @Override
    public Fragment getItem(int index) {

        if (ActivityMain.setdynamicTabs.get(index).equalsIgnoreCase("HOME")) {
            return new FragmentIndex();
        else {
            return new FragmentDynamicTab(index);
        }
    }

        @Override
public int getCount() {
    return ActivityMain.setdynamicTabs.size();
}

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // supertabLayout.destroyItemsetupWithViewPager(container, position, objectviewPager);
    }

    public void setCount(int count) {
        this.count = count;
    }
}

I am setting tablayout like this in java code

 if (viewPager != null) {
     viewPager.setAdapter(tabAdapter);
     tabLayout.setupWithViewPager(viewPager);
  }

I have gone through all possible solutions available for this error..But none of them is working. I am unable to trace what is causing this exception.Any help will be appreciated.

like image 625
Harry Sharma Avatar asked Aug 10 '15 05:08

Harry Sharma


1 Answers

Apparently commit() or commitAllowingStateLoss() happens twice inside FragmentStatePagerAdapter. Here what I found out from android sources:

The only place from where the transaction of this adapter is commited is FragmentStatePagerAdapter.finishUpdate() and it's commitAllowingStateLoss() version of commit(). Hence, finishUpdate() is called twice. This method is called from 3 places:

  • ViewPager.setAdapter();
  • ViewPager.dataSetChanged();
  • ViewPager.populate().

Now, finishUpdate() is protected by if (mCurTransaction != null) check and inside this check mCurTransaction is nulled. Hence we cannot really commit the same transaction twice. Unless we have multiple threads working on it. mCurTransaction field is not volatile, which leads me to idea that you're probably calling (directly or indirectly) one of the methods listed above from the worker thread and sometimes it leads to a race condition around mCurTransaction field, which leads to a second commitAllowingStateLoss() call.

Make sure you're referencing your adapter and related objects only from main (UI) thread.

like image 103
Dmide Avatar answered Oct 23 '22 09:10

Dmide