首先,我的应用程序的结构如下:
SpashActivity -> MainActivity -> switching between many fragments
我的应用程序使用SlideMenu在片段之间切换。我必须使用attach
而不是replace
保持片段状态。它看起来像:
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);
}
当后台堆栈倒数为零时,我的应用程序必须退出:
@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();
}
}
但有时(并非总是)我遇到异常并在用户多次按下时使我的应用程序崩溃(即使确认退出对话框也没有出现 - 意味着返回堆栈计数大于零):
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
onSaveInstanceState
方法:
@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);
}
}
你能告诉我我哪里错了吗?提前致谢。