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。 使用FragmentActivity
的WeakReference
解决了这个问题。 我的代码现在看起来如下:
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(); } }