2013-09-30 14 views
15

pierwsze, moja aplikacja ma strukturę tak:java.lang.IllegalStateException: Awaria zapisywania stanu: aktywny rozjaśniał indeks fragmentu

SpashActivity -> MainActivity -> switching between many fragments 

moim app korzystanie SlideMenu aby przełączać się między fragmentami. Muszę użyć attach zamiast replace, aby zachować stan fragmentu. To wygląda tak:

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

Kiedy liczyć z powrotem stos w dół do zera, moja aplikacja musi wyjść:

@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(); 
    } 
} 

Ale czasami (nie zawsze) Mam wyjątek i crash mój aplikacjach, gdy prasowe użytkownika z powrotem wiele razy (nawet dialogowe Potwierdź wyjście nie pojawiają - średnia tylną stosu liczyć większa niż 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 

The onSaveInstanceState meto 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); 
    } 
} 

Czy możesz mi powiedzieć, gdzie się myliłem? Z góry dziękuję.

+0

Znaleźliście jakieś rozwiązanie tego problemu? –

+1

Nie, ja po prostu dowiedzieć się, kiedy używam zastąpić zamiast odłączania i dołączania fragmentu, ten błąd nie występuje. – R4j

+0

Nie sądzę, że to rozwiązanie, w moim przypadku, dokonuję wymiany transakcji whick finish z tym błędem też:/ – letroll

Odpowiedz

0

Spróbuj zmienić

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

do

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

Mam nadzieję, że to działa

+0

Nie naprawia błędu dla mnie ... – Virthuss

0

Stan swoich fragmentów jest automatycznie zapisane i przywrócone, nie ma potrzeby, aby zrobić coś w Metoda onSaveInstanceState. Nie przechowuj żadnych odniesień do swoich Fragmentów w swojej Działalności (w twoim przypadku currentFragment, mContent), jeśli potrzebujesz określonego Fragmentu, pobierz go z FragmentManager przez np. findFragmentByTag.

0

Możliwy problem z odczytaniem statystyki fragmentu między odłączeniem a dołączaniem.

Spróbuj użyć czegoś takiego:

FragmentTransaction ft = fragmentManager.beginTransaction(); 

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

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