java.lang.IllegalStateException: no se puede realizar esta acción después de onSaveInstanceState

Estoy usando la biblioteca de soporte para mi aplicación. En mi FragmentActivity estoy usando AsyncTask para descargar datos de internet. En el método onPreExecute () agrego un Fragmento y en el método onPostExecute () lo elimino nuevamente. Cuando la orientación se cambia entre, obtengo la excepción mencionada anteriormente. Por favor, eche un vistazo a los detalles:

private class onFriendAddedAsyncTask extends AsyncTask { 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"); ... } 

Obtengo el siguiente 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) 

En otros hilos sobre problemas similares, la razón parece ser que se llama al método onPostExecute antes de llamar al método onResume (). Pero obtengo la excepción aunque onResume () se llama antes.

¿Alguien sabe lo que está mal?

La actividad se ve así:

 public class MyFragmentActivity extends FragmentActivity implements OnFriendSelectedListener, OnFriendAddedListener, OnFriendOptionSelectedListener, LoaderCallbacks { @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); } } 

Cuando uso commitAllowingStateLoss () obtengo la siguiente excepción:

 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) 

Obtengo la misma IllegalStateException cuando implemento AsynTask de la siguiente manera, porque el método findFragmentById () devuelve un puntero nulo.

 private class onFriendAddedAsyncTask extends AsyncTask { 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(); } 

En el siguiente paso, utilizo un controlador para agregar y eliminar el Fragmento de Fumigante. Además, he agregado más resultados de depuración.

 private class onFriendAddedAsyncTask extends AsyncTask { @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(); } }); 

Obtengo el siguiente 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) 

En onPreExecute (), FriendListFragment tiene id = 0x7f0a0002. Dentro del controlador, DummyFragment se crea con id = 0x7f0a0004. En onPostExecute () ambos ID son nulos. En onPreExecute (), la dirección de MyFragmentActivity es 45e38358. pero en onPostExecute () es nulo. Pero en ambos métodos, la dirección de FragmentManager es 45e384a8. Supongo que onPostExecute usa un FragmentManager no válido. ¿Pero por qué?

Debe hacer la transacción en un Handler siguiente manera:

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

Gracias Oleg Vaskevich. El uso de una WeakReference de FragmentActivity resolvió el problema. Mi código se ve de la siguiente manera:

 public class MyFragmentActivity extends FragmentActivity implements OnFriendAddedListener { private static WeakReference wrActivity = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); wrActivity = new WeakReference(this); ... private class onFriendAddedAsyncTask extends AsyncTask { @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(); } } 

Creo que la respuesta correcta a esta pregunta es el siguiente método.

 public abstract int commitAllowingStateLoss () 

Like commit () pero permite que la confirmación se ejecute después de guardar el estado de una actividad. Esto es peligroso porque la confirmación puede perderse si la actividad necesita ser restaurada más tarde desde su estado, por lo tanto, esto solo debe usarse para casos en los que está bien que el estado de la IU cambie inesperadamente en el usuario.

La descripción anterior se refiere a este método.

 protected void onSaveInstanceState(android.os.Bundle outState) 

Este problema ocurre precisamente cuando el dispositivo se va a dormir.

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

Solución corta y funcional:

Siga los pasos simples:

Paso 1 : onSaveInstanceState estado onSaveInstanceState en el fragmento respectivo. Y elimine el supermétodo de él.

 @Override public void onSaveInstanceState(Bundle outState) { } 

Paso 2 : use CommitAllowingStateLoss(); en lugar de commit(); mientras que las operaciones de fragmento.

 fragmentTransaction.commitAllowingStateLoss(); 

Verifique si la actividad es isFinishing() antes de mostrar el fragmento.

Ejemplo:

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

Tuve un problema similar que arreglé moviendo un fragmento de código de transacción de onResume() a onStart() .

Para ser más precisos: mi aplicación es un lanzador. Después de presionar el botón Inicio de Android, el usuario puede elegir un iniciador hasta que se recuerde su decisión. Al volver “atrás” en este punto (por ejemplo, tocando en el área grisácea), la aplicación se bloqueó.

Tal vez esto ayude a alguien.

Eso me pasó a mí, porque estaba invocando commit() desde el subfragmento que estaba filtrando actividad. Mantuvo la actividad como una propiedad y en una variable de actividad de rotación no fue actualizada por onAttach(); Así que estaba tratando de comprometer la transacción en la actividad zombie por (setRetainInstance(true);) retenido (setRetainInstance(true);) .

El motivo de la excepción es la recreación de FragmentActivity durante el tiempo de ejecución de AsyncTask y el acceso a la FragmentActivity anterior destruida en onPostExecute() posteriormente.

El problema es obtener una referencia válida para la nueva FragmentActivity . No hay un método para esto ni getActivity() ni findById() o algo similar. Este foro está lleno de hilos de acuerdo con este problema (por ejemplo, busca "Activity context in onPostExecute" ). Algunos de ellos describen soluciones temporales (hasta ahora no encontré uno bueno).

Quizás sería una mejor solución usar un Servicio para mi propósito.

Por lo que vale; Tuve este error en una aplicación que estaba ejecutando servicios en segundo plano. En uno de ellos, un diálogo de tiempo de espera debía mostrarse al usuario. Ese diálogo era el problema que causaba este error si la aplicación ya no se ejecutaba en primer plano.

En nuestro caso, mostrar el diálogo no fue útil cuando la aplicación estaba en segundo plano, así que solo hicimos un seguimiento de eso (boolean marcado onPause en onResume) y luego solo mostramos el diálogo cuando la aplicación es realmente visible para el usuario.

Solución 1: anule onSaveInstanceState() y elimine la supercarretera.

 @Override public void onSaveInstanceState(Bundle outState) { } 

Solución 2: anule onSaveInstanceState() y elimine su fragmento antes de la súper llamada

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

Este problema ocurre cuando un proceso intenta manipular una actividad cuyo onStop() ha sido llamado. No está necesariamente relacionado con la transacción de fragmentos, sino también con otros métodos como onBackPressed ().

Además de AsyncTask, otra fuente de dicho problema es la colocación incorrecta de la suscripción del patrón de bus. Habitualmente, la suscripción a EventBus o RxBus se registra durante el onCreate de Activity y se anula el registro en onDestroy. Si una nueva actividad comienza y publica un evento interceptado por los suscriptores de la actividad anterior, entonces puede producir este error. Si esto sucede, una solución es mover el registro de la suscripción y onStart() inscripción a onStart() y onStop() .

Hay una solución alternativa (NO la mejor) para este problema, pero funciona. Usando flag puedes manejarlo, como debajo

 /** * 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; ..... } 

Y puede verificar este valor boolean mientras realiza la transacción de fragmento.

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

Mi aplicación tiene un fragmento para cargar en 3 segundos, pero cuando la primera pantalla se está preparando para mostrar, presiono el botón de inicio y reanudo la ejecución, muestra el mismo error, por lo que editó mi código y funcionó muy bien:

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

NOTA: agregue commitAllowingStateLoss () en lugar de commit ()

A partir de la versión 24.0.0 de la biblioteca de soporte, puede llamar al método FragmentTransaction.commitNow() que confirma esta transacción de forma síncrona en lugar de llamar a commit() seguido de executePendingTransactions()

Utilice commitAllowingStateLoss() lugar de commit() .

cuando utiliza commit() , puede lanzar una excepción si se produce una pérdida de estado, pero commitAllowingStateLoss() guarda la transacción sin pérdida de estado para que no genere una excepción si se produce una pérdida de estado.

IllegalStateException se encuentra si comprometes cualquier fragmento de transacción después de que la actividad haya perdido su estado. La actividad no está en primer plano. Esto se encuentra comúnmente cuando intentas confirmar cualquier fragmento en AsyncTask o después de una solicitud de red.

Para evitar este locking, solo tiene que retrasar cualquier transacción de fragmento hasta que se restablezca el estado de la actividad. Siguiente es cómo se hace

Declarar dos variables booleanas privadas

 public class MainActivity extends AppCompatActivity { //Boolean variable to mark if the transaction is safe private boolean isTransactionSafe; //Boolean variable to mark if there is any transaction pending private boolean isTransactionPending; 

Ahora en onPostResume () y onPause establecemos y desarmamos nuestra variable booleana isTransactionSafe. La idea es marcar la trasnsacción como segura solo cuando la actividad esté en primer plano, por lo que no hay posibilidad de que se pierda el estado.

 /* onPostResume is called only when the activity's state is completely restred. In this we will set our boolean variable to true. Indicating that transaction is safe now */ public void onPostResume(){ super.onPostResume(); isTransactionSafe=true; } /* onPause is called just before the activity moves to background and also before onSaveInstanceState. In this we will mark the transaction as unsafe */ public void onPause(){ super.onPause(); isTransactionSafe=false; } private void commitFragment(){ if(isTransactionSafe) { MyFragment myFragment = new MyFragment(); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.frame, myFragment); fragmentTransaction.commit(); } } 

Lo que hemos hecho hasta ahora guardará de IllegalStateException, pero nuestras transacciones se perderán si se realizan después de que la actividad se transfiera a segundo plano, como commitAllowStateloss (). Para ayudar con eso, tenemos isTransactionPending variable booleana

 public void onPostResume(){ super.onPostResume(); isTransactionSafe=true; /* Here after the activity is restred we check if there is any transaction pending from the last restration */ if (isTransactionPending) { commitFragment(); } } private void commitFragment(){ if(isTransactionSafe) { MyFragment myFragment = new MyFragment(); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.frame, myFragment); fragmentTransaction.commit(); isTransactionPending=false; }else { /* If any transaction is not done because the activity is in background. We set the isTransactionPending variable to true so that we can pick this up when we come back to foreground */ isTransactionPending=true; } } 

Este artículo explica bastante detalladamente por qué se encuentra esta excepción y compara varios métodos para resolverla. Muy recomendable

Tuve la misma excepción e intenté muchos fragmentos que encontré aquí en esta discusión de stackoverflow, pero ningún fragmento me funcionó.

Pero pude resolver todos los problemas, voy a compartir con usted las soluciones:

  • En una primera parte: Intenté mostrar un DialogFragment en una actividad pero de otra clase de Java. Luego, al verificar el atributo de esa instancia, descubrí que era una instancia anterior de la Actividad, no era la Actividad en ejecución actual. [Más específicamente, estaba usando socket.io, y olvidé hacer un socket.off (“ejemplo”, ejemplo) … por lo que se adjuntó a una instancia anterior de la actividad. ]

  • En una segunda parte: estaba tratando de mostrar un DialogFragment en una actividad cuando volví con un bash, pero cuando revisé mis registros, vi que cuando trataba de mostrar el fragmento, la actividad aún no estaba en el método de inicio. , por lo que bloqueó la aplicación porque no encontró la clase Activity para mostrar el fragmento en ella.

Algunos consejos: verifique con algunos atributos si no está utilizando una instancia anterior de su actividad con la que está tratando de mostrar su fragmento, o verifique su ciclo de vida de actividad antes de mostrar su fragmento y asegúrese de estar en inicio o en Mostrar antes de mostrarlo .

Espero que esas explicaciones te ayuden.