2015-08-10 13 views
16

Sto usando View pager con Tablayout nel mio progetto. Ricevo continuamente un rapporto sugli arresti anomali. Di seguito è riportata la traccia dello stack.java.lang.IllegalStateException: commit già chiamato in visualizzazione pager con Tablayout

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) 

Ecco il mio file xml

<?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> 

codice adattatore

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

io pongo tablayout come questo in codice Java

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

mi sono passati attraverso tutti i possibili soluzioni disponibili per questo errore ... ma nessuno di loro funziona. Non riesco a rintracciare ciò che sta causando questa eccezione. Qualsiasi aiuto sarà apprezzato.

+0

fornire qualche codice, come ti configurare il TabLayout, a quale linea si pianta? Questo non è davvero utile. – Marko

+0

per favore vedi la mia domanda modificata .. Non posso vedere dove si blocca perché non sto andando in crash sui miei dispositivi, ma su crashlytics sto ottenendo questo crash .. –

+0

Puoi aggiungere il codice per l'adattatore e, probabilmente stai aggiungendo frammenti lì. – Marko

risposta

3

Apparentemente commit() o commitAllowingStateLoss() si verifica due volte all'interno di FragmentStatePagerAdapter. Ecco cosa ho scoperto da fonti Android:

L'unico luogo da cui viene eseguita la transazione di questa scheda è FragmentStatePagerAdapter.finishUpdate() ed è la versione commitAllowingStateLoss() di commit(). Quindi, finishUpdate() viene chiamato due volte. Questo metodo viene chiamato da 3 posti:

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

Ora, finishUpdate() è protetto da if (mCurTransaction != null) controllo e all'interno di questo controllo mCurTransaction viene reso nullo. Quindi non possiamo davvero commettere la stessa transazione due volte. A meno che non abbiamo più thread su di esso. Il campo mCurTransaction non è volatile, il che mi porta a pensare che probabilmente stai chiamando (direttamente o indirettamente) uno dei metodi sopra elencati dal thread di lavoro e talvolta conduce a una condizione di gara intorno al campo mCurTransaction, che porta a un secondo commitAllowingStateLoss() chiamata.

Assicurarsi di fare riferimento all'adattatore e agli oggetti correlati solo dal thread principale (UI).

+0

Non ha funzionato .. !! –

-1

Questo codice sembra molto familiare.

Sembra il mio progetto MaterialAppBase in github, ma questo non è il mio codice.

Ho letto il tuo codice, se non sbaglio, hai un'attività che implementa un cassetto di navigazione allo stesso tempo, viene implementato un tablayout.

Questa non è comunque una buona idea. Vedo che hai a che fare con un'app che forse ha un layout molto complicato.

Quello che stai facendo è contro la linea guida di progettazione Android, di causa contro il normale design UX. Non dovresti mai avere due viste scorrevoli come navigazione all'interno di un'attività. E il gesto di scorrimento tra NavigationDrawer e ViewPager potrebbe essere in conflitto. Pensaci, nessuno lo fa.

Tuttavia, molti hanno le tue ragioni per farlo.Se consisti di fare ciò, vedo qualcosa di sbagliato nel tuo codice, ma non sono sicuro che il tuo problema sia causato da questo errore.

@Override 
public Fragment getItem(int index) { 

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

Problema: non è necessario creare un nuovo frammento ogni volta che viene eseguito il rendering dell'elemento di pagina.

Che cosa si dovrebbe fare è:

  • si dovrebbe avere il frammenti creata in anticipo.
  • Aggiungi i tuoi frammenti in ArrayList o qualcosa del genere.
  • Passa questo elenco all'adattatore e in modo che possa rendere riutilizzabili i frammenti.

Guardate il mio codice the adapter code

+0

Il codice di esempio di [utilizzando l'adattatore] (https://github.com/DanielShum/MaterialAppBase/blob/master/app/src/main/java/com/daililol/material/appbase/example/ExampleTabbarActivity.java) –

Problemi correlati