java.lang.IllegalStateException:在onSaveInstanceState后无法执行此操作

我正在使用我的应用程序的支持库。 在我的FragmentActivity我使用AsyncTask从互联网上下载数据。 在onPreExecute()方法中,我添加一个片段,并在onPostExecute()方法中再次删除它。 当方向改变时,我得到了上述例外。 请看看细节:

private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> { DummyFragment dummyFragment; FragmentManager fm; FragmentTransaction ft; @Override protected void onPreExecute() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute"); dummyFragment = DummyFragment.newInstance(); fm = getSupportFragmentManager(); ft = fm.beginTransaction(); ft.add(dummyFragment, "dummy_fragment"); ft.commit(); } @Override protected void onPostExecute(String result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute"); ft = fm.beginTransaction(); ft.remove(dummyFragment); ft.commit(); } @Override protected String doInBackground(String... name) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/doInBackground"); ... } 

我得到以下LogCut:

 01-05 23:54:19.958: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPreExecute 01-05 23:54:19.968: V/DummyFragment(12783): onAttach 01-05 23:54:19.968: V/DummyFragment(12783): onCreate 01-05 23:54:19.968: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/doInBackground 01-05 23:54:19.973: V/DummyFragment(12783): onCreateView 01-05 23:54:19.973: V/DummyFragment(12783): onActivityCreated 01-05 23:54:19.973: V/DummyFragment(12783): onStart 01-05 23:54:19.973: V/DummyFragment(12783): onResume 01-05 23:54:21.933: V/MyFragmentActivity(12783): onSaveInstanceState 01-05 23:54:21.933: V/DummyFragment(12783): onSaveInstanceState 01-05 23:54:21.933: V/MyFragmentActivity(12783): onPause 01-05 23:54:21.933: V/DummyFragment(12783): onPause 01-05 23:54:21.938: V/MyFragmentActivity(12783): onStop 01-05 23:54:21.938: V/DummyFragment(12783): onStop 01-05 23:54:21.938: V/MyFragmentActivity(12783): onDestroy 01-05 23:54:21.938: V/DummyFragment(12783): onDestroyView 01-05 23:54:21.938: V/DummyFragment(12783): onDestroy 01-05 23:54:21.938: V/DummyFragment(12783): onDetach 01-05 23:54:21.978: V/MyFragmentActivity(12783): onCreate 01-05 23:54:21.978: V/DummyFragment(12783): onAttach 01-05 23:54:21.978: V/DummyFragment(12783): onCreate 01-05 23:54:22.263: V/MyFragmentActivity(12783): onStart 01-05 23:54:22.313: V/DummyFragment(12783): onCreateView 01-05 23:54:22.313: V/DummyFragment(12783): onActivityCreated 01-05 23:54:22.313: V/DummyFragment(12783): onStart 01-05 23:54:22.323: V/MyFragmentActivity(12783): onResume 01-05 23:54:22.323: V/MyFragmentActivity(12783): onPostResume 01-05 23:54:22.323: V/MyFragmentActivity(12783): onResumeFragments 01-05 23:54:22.323: V/DummyFragment(12783): onResume 01-05 23:54:27.123: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPostExecute 01-05 23:54:27.123: D/AndroidRuntime(12783): Shutting down VM 01-05 23:54:27.123: W/dalvikvm(12783): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0) 01-05 23:54:27.138: E/AndroidRuntime(12783): FATAL EXCEPTION: main 01-05 23:54:27.138: E/AndroidRuntime(12783): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1325) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:532) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:447) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:1) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask.finish(AsyncTask.java:417) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask.access$300(AsyncTask.java:127) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.Handler.dispatchMessage(Handler.java:99) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.Looper.loop(Looper.java:123) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.app.ActivityThread.main(ActivityThread.java:4627) 01-05 23:54:27.138: E/AndroidRuntime(12783): at java.lang.reflect.Method.invokeNative(Native Method) 01-05 23:54:27.138: E/AndroidRuntime(12783): at java.lang.reflect.Method.invoke(Method.java:521) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 01-05 23:54:27.138: E/AndroidRuntime(12783): at dalvik.system.NativeStart.main(Native Method) 

在关于类似问题的其他线程中,原因似乎是在onResume()方法被调用之前调用onPostExecute方法。 但即使onResume()之前被调用,我也会得到exception。

有人知道什么是错的吗?

活动看起来像这样:

 public class MyFragmentActivity extends FragmentActivity implements OnFriendSelectedListener, OnFriendAddedListener, OnFriendOptionSelectedListener, LoaderCallbacks<Cursor> { @Override public void onCreate(Bundle savedInstanceState) { Log.v("MyFragmentActivity", "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.fragment_activity_layout); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); FriendListFragment friendListFragment = (FriendListFragment)fm.findFragmentById(R.id.friend_list_fragment_layout); if (friendListFragment == null) { friendListFragment = new FriendListFragment(); ft.add(R.id.friend_list_fragment_layout, friendListFragment); ft.commit(); fm.executePendingTransactions(); startService(new Intent(this, MyIntentService.class)); getSupportLoaderManager().initLoader(CHECK_EMPTY_DATABASE, null, this); } } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.fragment_activity_options_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); switch (item.getItemId()) { case R.id.add_friend_menu_item: AddFriendDialogFragment addFriendDialogFragment = AddFriendDialogFragment.newInstance(); addFriendDialogFragment.show(getSupportFragmentManager(), "add_friend_dialog_fragment"); return true; default: return false; } } @Override public void onFriendAdded(String name) { name = name.trim(); if (name.length() > 0) { new onFriendAddedAsyncTask().execute(name); } } 

当使用commitAllowingStateLoss()我得到以下exception:

 01-06 14:54:29.548: E/AndroidRuntime(18020): FATAL EXCEPTION: main 01-06 14:54:29.548: E/AndroidRuntime(18020): java.lang.IllegalStateException: Activity has been destroyed 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:461) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:1) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask.finish(AsyncTask.java:417) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask.access$300(AsyncTask.java:127) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.Handler.dispatchMessage(Handler.java:99) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.Looper.loop(Looper.java:123) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.app.ActivityThread.main(ActivityThread.java:4627) 01-06 14:54:29.548: E/AndroidRuntime(18020): at java.lang.reflect.Method.invokeNative(Native Method) 01-06 14:54:29.548: E/AndroidRuntime(18020): at java.lang.reflect.Method.invoke(Method.java:521) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 01-06 14:54:29.548: E/AndroidRuntime(18020): at dalvik.system.NativeStart.main(Native Method) 

当我如下执行AsynTask时,我得到相同的IllegalStateExeption,因为findFragmentById()方法返回一个空指针。

 private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> { protected void onPreExecute() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute"); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commit(); } protected void onPostExecute(String result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute"); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout); ft.remove(dummyFragment); ft.commitAllowingStateLoss(); } 

在下一步我使用一个处理程序添加和删除DummyFragment。 另外我添加了一些更多的debugging输出。

 private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> { @Override protected void onPreExecute() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); new Handler().post(new Runnable() { public void run() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commit(); } }); @Override protected void onPostExecute(String result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); new Handler().post(new Runnable() { public void run() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout); ft.remove(dummyFragment); ft.commitAllowingStateLoss(); } }); 

我得到以下LogCut:

 01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}} 01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null 01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002} 01-07 19:00:17.283: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}} 01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/doInBackground 01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null 01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002} 01-07 19:00:17.308: V/DummyFragment(4124): onAttach DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onCreate DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onCreateView DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onActivityCreated DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onStart DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.313: V/DummyFragment(4124): onResume DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/MyFragmentActivity(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/DummyFragment(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/MyFragmentActivity(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/DummyFragment(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/MyFragmentActivity(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/DummyFragment(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/MyFragmentActivity(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/DummyFragment(4124): onDestroyView DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.108: V/DummyFragment(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.113: V/DummyFragment(4124): onDetach DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.138: V/MyFragmentActivity(4124): onCreate 01-07 19:00:18.138: V/FriendListFragment(4124): FriendListFragment 01-07 19:00:18.138: V/FriendListFragment(4124): onAttach FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.138: V/FriendListFragment(4124): onCreate FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.148: V/DummyFragment(4124): onAttach DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.153: V/DummyFragment(4124): onCreate DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.523: V/MyFragmentActivity(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.543: V/FriendListFragment(4124): onActivityCreated FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.548: V/DummyFragment(4124): onCreateView DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.548: V/DummyFragment(4124): onActivityCreated DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}} 01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.553: V/DummyFragment(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}} 01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.558: V/MyFragmentActivity(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.558: V/MyFragmentActivity(4124): onPostResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.558: V/MyFragmentActivity(4124): onResumeFragments DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.558: V/FriendListFragment(4124): onResume FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.563: V/FriendListFragment(4124): onCreateLoader FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.563: V/DummyFragment(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}} 01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}} 01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}} 01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.928: D/AndroidRuntime(4124): Shutting down VM 01-07 19:00:18.928: W/dalvikvm(4124): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0) 01-07 19:00:18.938: E/AndroidRuntime(4124): FATAL EXCEPTION: main 01-07 19:00:18.938: E/AndroidRuntime(4124): java.lang.IllegalStateException: Activity has been destroyed 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536) 01-07 19:00:18.938: E/AndroidRuntime(4124): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask$2.run(MyFragmentActivity.java:476) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Handler.handleCallback(Handler.java:587) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Handler.dispatchMessage(Handler.java:92) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Looper.loop(Looper.java:123) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.app.ActivityThread.main(ActivityThread.java:4627) 01-07 19:00:18.938: E/AndroidRuntime(4124): at java.lang.reflect.Method.invokeNative(Native Method) 01-07 19:00:18.938: E/AndroidRuntime(4124): at java.lang.reflect.Method.invoke(Method.java:521) 01-07 19:00:18.938: E/AndroidRuntime(4124): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 01-07 19:00:18.938: E/AndroidRuntime(4124): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 01-07 19:00:18.938: E/AndroidRuntime(4124): at dalvik.system.NativeStart.main(Native Method) 

在onPreExecute()中,FriendListFragment的id = 0x7f0a0002。 在处理程序中,创buildDummyFragment,id = 0x7f0a0004。 在onPostExecute()这两个ID都是空的。 在onPreExecute()MyFragmentActivity的地址是45e38358。 但在onPostExecute()它是空的。 但是在这两种方法中,FragmentManager的地址是45e384a8。 我想onPostExecute使用无效的FragmentManager。 但为什么?

您应该如下Handler的事务:

 @Override protected void onPostExecute(String result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute"); new Handler().post(new Runnable() { public void run() { fm = getSupportFragmentManager(); ft = fm.beginTransaction(); ft.remove(dummyFragment); ft.commit(); } }); } 

感谢Oleg Vaskevich。 使用FragmentActivityWeakReference解决了这个问题。 我的代码现在看起来如下:

 public class MyFragmentActivity extends FragmentActivity implements OnFriendAddedListener { private static WeakReference<MyFragmentActivity> wrActivity = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); wrActivity = new WeakReference<MyFragmentActivity>(this); ... private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> { @Override protected void onPreExecute() { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commit(); } @Override protected void onPostExecute(String result) { final Activity activity = wrActivity.get(); if (activity != null && !activity.isFinishing()) { FragmentManager fm = activity.getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout); ft.remove(dummyFragment); ft.commitAllowingStateLoss(); } } 

我相信这个问题的正确答案是以下方法。

 public abstract int commitAllowingStateLoss () 

像commit()一样,但是允许在一个activity的状态被保存之后执行commit。 这是很危险的,因为如果活动需要稍后从其状态恢复,那么提交可能会丢失,所以这应该只用于UI状态在用户意外改变的情况下。

以上描述涉及这种方法。

 protected void onSaveInstanceState(android.os.Bundle outState) 

这个问题恰好发生在设备进入睡眠状态时。

http://developer.android.com/reference/android/app/FragmentTransaction.html

简短和工作解决scheme:

遵循简单的步骤:

第1步 :覆盖相应片段中的onSaveInstanceState状态。 并从中删除超级方法。

 @Override public void onSaveInstanceState(Bundle outState) { } 

第2步 :使用CommitAllowingStateLoss(); 而不是commit(); 而片段操作。

 fragmentTransaction.commitAllowingStateLoss(); 

在显示片段之前检查活动是否为isFinishing()

例:

 if(!isFinishing()) { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commitAllowingStateLoss(); } 

我有一个类似的问题,我通过将一些片段事务代码从onResume()onStart()

更确切地说:我的应用程序是一个启动器。 按下Android主页button后,用户可以select一个启动器,直到他/她的决定被记住。 当在这个时候回退(例如通过在灰色区域敲击)应用程序崩溃。

也许这有助于某人。

这发生在我身上,因为我从正在泄漏活动的子片段调用commit() 。 它保持活动作为一个属性和旋转活动variables不更新onAttach(); 所以我试图通过保留(setRetainInstance(true);)片段来提交僵尸Activity上的事务。

exception的原因是在AsyncTask运行期间重新创buildFragmentActivity ,然后在onPostExecute()之后访问以前销毁的FragmentActivity

问题是获得新的FragmentActivity的有效参考。 没有方法既不getActivity()也不findById()或类似的东西。 这个论坛充满了根据这个问题的线程(例如search"Activity context in onPostExecute" )。 其中一些正在描述解决方法(直到现在我没有find一个好的)。

也许这将是一个更好的解决scheme,使用服务为我的目的。

物有所值; 我在后台运行服务的应用程序出现此错误。 在其中一个超时对话框必须显示给用户。 该对话框是导致此错误的问题,如果应用程序不再在前台运行。

在我们的例子中,当应用程序在后台时显示对话框没有用,所以我们只是跟踪(boolean标记的onPause和onResume),然后只显示对话框,当用户真正看到应用程序时。

解决scheme1:重写onSaveInstanceState()并删除超级调用。

 @Override public void onSaveInstanceState(Bundle outState) { } 

解决scheme2:重写onSaveInstanceState()并在超级调用之前删除您的片段

 @Override public void onSaveInstanceState(Bundle outState) { // TODO: Add code to remove fragment here super.onSaveInstanceState(outState); } 

当一个进程试图操作其onStop()被调用的Activity时,就会发生这个问题。 它不一定绑定到片段事务,但也可以像onBackPressed()这样的其他方法。

除了AsyncTask之外,这种问题的另一个来源是总线模式订阅的错位。 通常事件总线或RxBus的订阅在Activity的onCreate中注册并在onDestroy中注销。 如果一个新的Activity启动并发布一个事件从前一个Activity中拦截的事件,那么它可能会产生这个错误。 如果发生这种情况,一个解决scheme是将订阅注册和注销注册到onStart()onStop()

我的应用程序有一个片段要加载在3秒,但是当第一个屏幕准备显示,我按Home键并继续运行它,它显示相同的错误,所以它编辑我的代码,它运行非常stream畅:

 new Handler().post(new Runnable() { public void run() { if (saveIns == null) { mFragment = new Fragment_S1_loading(); getFragmentManager().beginTransaction() .replace(R.id.container, mFragment).commit(); } getActionBar().hide(); // Loading screen in 3 secs: mCountDownTimerLoading = new CountDownTimer(3000, 1000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { if (saveIns == null) {// TODO bug when start app and press home // button getFragmentManager() .beginTransaction() .replace(R.id.container, new Fragment_S2_sesstion1()).commitAllowingStateLoss(); } getActionBar().show(); } }.start(); } }); 

注意:添加commitAllowingStateLoss()而不是commit()

从支持库版本24.0.0开始,您可以调用同步提交此事务的FragmentTransaction.commitNow()方法,而不是先调用commit() ,再执行executePendingTransactions()

有一个替代解决scheme(不是最好的解决scheme)这个问题,但工程。 使用国旗,你可以处理它,就像下面

 /** * Flag to avoid "java.lang.IllegalStateException: Can not perform this action after * onSaveInstanceState". Avoid Fragment transaction until onRestoreInstanceState or onResume * gets called. */ private boolean isOnSaveInstanceStateCalled = false; @Override public void onRestoreInstanceState(final Bundle bundle) { ..... isOnSaveInstanceStateCalled = false; ..... } @Override public void onSaveInstanceState(final Bundle outState) { ..... isOnSaveInstanceStateCalled = true; ..... } @Override public void onResume() { super.onResume(); isOnSaveInstanceStateCalled = false; ..... } 

你可以在做片段事务时检查这个boolean值。

 private void fragmentReplace(Fragment fragment, String fragmentTag){ if (!isOnSaveInstanceStateCalled) { getSupportFragmentManager() .beginTransaction() .replace(R.id.layout_container, fragment, fragmentTag) .commit(); } }