studio programacion para herramientas fundamentos desarrollo con avanzado aplicaciones android exception android-asynctask android-fragments illegalstateexception

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



manual android studio avanzado (14)

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

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

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

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

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

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é?


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


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


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.


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


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() .


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


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


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


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.


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


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