2013-09-30 9 views
15

In primo luogo, la mia app ha una struttura come questa:java.lang.IllegalStateException: Guasto stato di risparmio: attiva ha eliminato indice nel frammento

SpashActivity -> MainActivity -> switching between many fragments 

Il mio uso app SlideMenu per passare tra i frammenti. Devo usare attach invece di replace per mantenere lo stato dei frammenti. E 'sembrare:

public void switchContent(int index, String fragmentTag) {     
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    FragmentTransaction transaction = fragmentManager.beginTransaction(); 
    if (fragmentManager.findFragmentByTag(fragmentTag) != mContent) { 
     if (!mContent.isDetached()) { 
      transaction.detach(mContent); 
     } 
     if (null == fragmentManager.findFragmentByTag(fragmentTag)) { 
      switch (index) { 
      case 0: 
       mContent = new CategoryFragment(); 
       break; 
      case 1: 
       mContent = new BookFragment(); 
       break; 
      case 2: 
       mContent = new BookDetailFragment(); 
       break; 
      // etc 
      } 
     } else { 
       mContent = fragmentManager.findFragmentByTag(fragmentTag);    
     } 

     if (mContent.isDetached()) { 
      transaction.attach(mContent); 
     } else if (!mContent.isAdded()) { 
      transaction.add(R.id.content_frame, mContent, fragmentTag); 
     } 

     transaction.addToBackStack(null); 
     transaction.commit(); 
     fragmentManager.executePendingTransactions(); 
    } 
    Handler h = new Handler(); 
    h.postDelayed(new Runnable() { 
     public void run() { 
      getSlidingMenu().showContent(); 
     } 
    }, 50); 
} 

Quando conta la pila di nuovo a zero, la mia applicazione deve uscire:

@Override 
public void onBackPressed() { 
    if (0 == getSupportFragmentManager().getBackStackEntryCount()) { 
     // show confirm exit dialog. 
     // If user press ok, try to exit, the splash activity will call finish() 
     // if(dialog == ok){ 
      Intent intent = new Intent(MainActivity.this, SplashActivity.class); 
      intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
      intent.putExtra(SplashActivity.EXIT_KEY, true); 
      startActivity(intent); 
     // } 
    } else { 
     super.onBackPressed(); 
    } 
} 

Ma volte (non sempre) ho avuto l'eccezione e crash la mia app quando utente preme indietro molte volte (anche la finestra di uscita di conferma non compaiono - significa tornare pila conteggio maggiore di zero):

09-30 20:32:53.419: E/AndroidRuntime(796): Uncaught handler: thread main exiting due to uncaught exception 
    09-30 20:32:53.470: E/AndroidRuntime(796): java.lang.RuntimeException: Unable to pause activity {com.org.scgroup/com.org.scgroup.MainActivity}: java.lang.IllegalStateException: Failure saving state: active BookDetailFragment{43e7e0d8} has cleared index: -1 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3162) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3119) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3102) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.ActivityThread.access$2400(ActivityThread.java:119) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.os.Handler.dispatchMessage(Handler.java:99) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.os.Looper.loop(Looper.java:123) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.ActivityThread.main(ActivityThread.java:4363) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at java.lang.reflect.Method.invokeNative(Native Method) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at java.lang.reflect.Method.invoke(Method.java:521) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at dalvik.system.NativeStart.main(Native Method) 
    09-30 20:32:53.470: E/AndroidRuntime(796): Caused by: java.lang.IllegalStateException: Failure saving state: active BookDetailFragment{43e7e0d8} has cleared index: -1 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1716) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:532) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at com.actionbarsherlock.app.SherlockFragmentActivity.onSaveInstanceState(SherlockFragmentActivity.java:126) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity.onSaveInstanceState(SlidingFragmentActivity.java:51) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at com.org.scgroup.MainActivity.onSaveInstanceState(MainActivity.java:324) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.Activity.performSaveInstanceState(Activity.java:1022) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1180) 
    09-30 20:32:53.470: E/AndroidRuntime(796): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3144) 
    09-30 20:32:53.470: E/AndroidRuntime(796): ... 12 more 

il onSaveInstanceState metho d:

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    try { 
     Ln.d("onSaveInstanceState"); 
     outState.putInt(CURRENT_FRAGMENT_KEY, currentFragment); 

     if (0 < getSupportFragmentManager().getBackStackEntryCount()) { 
      getSupportFragmentManager().putFragment(outState, "mContent", mContent); 
     } 
    } catch (Exception ex) { 
     Ln.e(ex); 
    } 
} 

Potrebbe dirmi dove mi sbaglio? Grazie in anticipo.

+0

Hai trovato una soluzione per questo problema? –

+1

No, ho appena capito quando uso la sostituzione invece di staccare e collegare il frammento, questo errore non si è verificato. – R4j

+0

Non penso che sia la soluzione, nel mio caso, faccio una transazione di sostituzione che termina anche con questo errore:/ – letroll

risposta

0

tenta di modificare

@Override 
public void onBackPressed() { 
    if (0 == getSupportFragmentManager().getBackStackEntryCount()) { 

a

@Override 
public void onBackPressed() { 
    if (getSupportFragmentManager().getBackStackEntryCount() < 1) { 

Spero che questo funziona

+0

Non aggiusta l'errore per me ... – Virthuss

0

Lo stato dei tuoi frammenti viene salvato e ripristinato automaticamente, non c'è bisogno di fare nulla nella vostra Metodo onSaveInstanceState. Non tenere alcun riferimento ai tuoi frammenti nella tua attività (nel tuo caso currentFragment, mContent), se hai bisogno di un certo frammento, prendilo da FragmentManager ad es. findFragmentByTag.

0

Possibile problema con la lettura di frammenti di stato tra il distacco e il collegamento.

tenta di utilizzare qualcosa di simile:

FragmentTransaction ft = fragmentManager.beginTransaction(); 

//ft.detach(fragment).attach(fragment).commitAllowingStateLoss(); // crashing 

ft.replace(getView().getId(), fragment).commitAllowingStateLoss(); // not crashing 
Problemi correlati