“Resultado de falla de entrega” – onActivityForResult

Tengo una LoginActivity (el usuario LoginActivity ). Básicamente, es su propia Activity que tiene el tema de un diálogo (para aparecer como un diálogo). Aparece sobre SherlockFragmentActivity . Lo que quiero es: si hay un inicio de sesión exitoso, debe haber dos FragmentTransaction para actualizar la vista. Aquí está el código:

En LoginActivity , si el inicio de sesión es exitoso,

 setResult(1, new Intent()); 

En SherlockFragmentActivity :

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == 1) { LoggedStatus = PrefActivity.getUserLoggedInStatus(this); FragmentTransaction t = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction(); SherlockListFragment mFrag = new MasterFragment(); t.replace(R.id.menu_frame, mFrag); t.commit(); // Set up Main Screen FragmentTransaction t2 = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction(); SherlockListFragment mainFrag = new FeaturedFragment(); t2.replace(R.id.main_frag, mainFrag); t2.commit(); } } 

Se bloquea en el primer commit, con este LogCat:

 E/AndroidRuntime(32072): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState E/AndroidRuntime(32072): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299) E/AndroidRuntime(32072): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) E/AndroidRuntime(32072): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) E/AndroidRuntime(32072): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) E/AndroidRuntime(32072): at com.kickinglettuce.rate_this.MainFragmentActivity.onActivityResult(MainFragmentActivity.java:243) E/AndroidRuntime(32072): at android.app.Activity.dispatchActivityResult(Activity.java:5293) E/AndroidRuntime(32072): at android.app.ActivityThread.deliverResults(ActivityThread.java:3315) 

Antes que nada, deberías leer mi publicación en el blog para más información (habla sobre por qué ocurre esta excepción y qué puedes hacer para evitarla).

Llamar a commitAllowingStateLoss() es más un hack que una solución. La pérdida del estado es mala y debe evitarse a toda costa. En el momento en que se llama a onActivityResult() es posible que el estado de la actividad / fragmento aún no se haya restaurado y, por lo tanto, cualquier transacción que ocurra durante este tiempo se perderá como resultado. ¡Este es un error muy importante que debe ser abordado! (Tenga en cuenta que el error solo ocurre cuando su Activity regresa después de haber sido asesinado por el sistema … que, dependiendo de la cantidad de memoria que tenga el dispositivo, a veces puede ser raro … por lo que este tipo de error no es algo que es muy fácil de atrapar mientras se prueba).

Intente mover sus transacciones a onPostResume() lugar (tenga en cuenta que onPostResume() siempre se llama después de onResume() y onResume() siempre se llama después de onActivityResult() ):

 private boolean mReturningWithResult = false; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mReturningWithResult = true; } @Override protected void onPostResume() { super.onPostResume(); if (mReturningWithResult) { // Commit your transactions here. } // Reset the boolean flag back to false for next time. mReturningWithResult = false; } 

Esto puede parecer un poco extraño, pero hacer este tipo de cosas es necesario para garantizar que tus FragmentTransaction s siempre se comprometan después de que el estado de la Activity se haya restaurado a su estado original onPostResume() se garantiza que se llamará a onPostResume() después de la Activity ‘ s estado ha sido restaurado).

Esto es similar a la respuesta de @Alex Lockwood pero usando un Runnable :

 private Runnable mOnActivityResultTask; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mOnActivityResultTask = new Runnable() { @Override public void run() { // Your code here } } } @Override protected void onPostResume() { super.onPostResume(); if (mOnActivityResultTask != null) { mOnActivityResultTask.run(); mOnActivityResultTask = null; } } 

En caso de que esté ejecutando Android 3.0 y superior con lambdas , use esto:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mOnActivityResultTask = () -> { // Your code here } } 

En mi caso me enfrenté a los mismos problemas debido a lo siguiente

 public void onBackPressed() { super.onBackPressed(); setIntents(); } private void setIntents(){ Intent searchConstaints=new Intent(); searchConstaints.putExtra("min",20); searchConstaints.putExtra("max",80); setResult(101,searchConstaints); finish(); } 

Resuelto mediante la reorganización de la función Llamadas en onBackPressed ()

 public void onBackPressed() { setIntents(); super.onBackPressed(); } 

Puede usar ft.commitAllowingStateLoss() para resolver este problema.

Motivo: el método ft.commit() se onSaveInstanceState después de onSaveInstanceState .

su logcat dice claramente: “No se puede realizar esta acción después de onSaveInstanceState” : su Activity ya está muerta en ese punto y no pudo devolver ningún resultado.

sólo muévete:

 Intent in = new Intent(); setResult(1, in); 

al lugar de tu Activity donde todavía está vivo, y todo estará bien. y no olvide finish() su Activity para entregar el resultado.