Cualquier efecto secundario para resolver "No se puede realizar esta acción después de onSaveInstanceState" mediante commitAllowingStateLoss

Anteriormente, no tenemos ningún problema para mostrar el siguiente DialogFragment

introduzca la descripción de la imagen aquí

 // Triggered by button click. private void openFromCloud() { LoadFromCloudTaskFragment loadFromCloudTaskFragment = new LoadFromCloudTaskFragment(); FragmentManager fm = this.getSupportFragmentManager(); fm.beginTransaction().add(loadFromCloudTaskFragment, "loadFromCloudTaskFragment").commit(); } 

Sin embargo, si tendemos a mostrar el mismo DialogFragment después de presionar el botón OK en el Intent siguiente, se producirá un error.

introduzca la descripción de la imagen aquí

 private void openFromCloud() { startActivityForResult(Utils.getGoogleAccountCredential().newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER); } @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { switch (requestCode) { case REQUEST_ACCOUNT_PICKER: if (resultCode == RESULT_OK && data != null && data.getExtras() != null) { String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); if (accountName != null) { Utils.getGoogleAccountCredential().setSelectedAccountName(accountName); LoadFromCloudTaskFragment loadFromCloudTaskFragment = new LoadFromCloudTaskFragment(); FragmentManager fm = getSupportFragmentManager(); fm.beginTransaction().add(loadFromCloudTaskFragment, "loadFromCloudTaskFragment").commit(); } } break; } } 

Aquí está el registro de errores detallado

 FATAL EXCEPTION: main java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { (has extras) }} to activity {org.yccheok.xxx.gui/org.yccheok.xxx.gui.XXXFragmentActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.app.ActivityThread.deliverResults(ActivityThread.java:3141) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3184) at android.app.ActivityThread.access$1100(ActivityThread.java:130) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1243) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299) at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) at org.yccheok.xxx.gui.XXXFragmentActivity$1.run(XXXFragmentActivity.java:107) at android.app.Activity.runOnUiThread(Activity.java:4591) at org.yccheok.xxx.gui.XXXFragmentActivity.onActivityResult(XXXFragmentActivity.java:102) at android.app.Activity.dispatchActivityResult(Activity.java:5192) at android.app.ActivityThread.deliverResults(ActivityThread.java:3137) ... 11 more 

Puedo simplemente "solucionar" el problema utilizando commitAllowingStateLoss lugar de commit .

 fm.beginTransaction().add(loadFromCloudTaskFragment, "loadFromCloudTaskFragment").commitAllowingStateLoss(); 

Realmente no entiendo la documentación relativa commitAllowingStateLoss .

Como commit () pero permite que el commit se ejecute después de que se guarde el estado de una actividad. Esto es peligroso porque el commit se puede perder si la actividad necesita restaurarse más tarde de su estado, por lo que sólo se debe utilizar en casos en los que está bien que el estado de la interfaz de usuario cambie inesperadamente en el usuario.

Esto se basa en la sugerencia de obtener excepción "IllegalStateException: No se puede realizar esta acción después de OnSaveInstanceState"

Realmente no entiendo el punto que está bien para que el estado de la interfaz de usuario cambie inesperadamente en el usuario. ? ¿Puedo saber cuál es el posible efecto secundario del uso de commitAllowingStateLoss ? ¿Puedo producir algún efecto secundario?

Lo único que se me ocurre es una especie de "condición de carrera".

Imagine una situación, cuando el dispositivo se está girando justo antes de la llamada commitAllowingStateLoss() . AFAIK, ocurre lo siguiente:

  • onSaveInstanceState() callback (almacén de la actividad es estado con ningún fragmento presente en el momento (puesto que usted no ha cometido cualquier cosa todavía)
  • commitAllowingStateLoss se ejecuta agregando fragmento a la actividad
  • Activity se recrea, restaurando su estado al momento, cuando no se agregó tu fragmento

En mi opinión, causa situaciones difícilmente previsibles, tales como:

  • java.lang.IllegalStateException: Failure saving state: FragmentB has target not in fragment manager: FragmentA si está utilizando Fragment.setTargetFragment() por cualquier razón
  • su fragmento puede simplemente faltar en la vista

De todos modos, no estoy 100% seguro de eso, pero estoy teniendo mucho inesperado java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState excepciones java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState en mi aplicación, y tratando de encontrar una solución también.

Probablemente ya no tienes este problema. Tengo un problema similar. Resolví poner código de transición de fragmento en la función onResume. He puesto una bandera para indicar si el resultado era aceptable. Si es verdad entonces dentro del método de onResume hice la transición a otro Fragmento.

Puedes ver el código de seguimiento en Activity.java

  protected void onSaveInstanceState(Bundle outState) { outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState()); Parcelable p = mFragments.saveAllState(); if (p != null) { outState.putParcelable(FRAGMENTS_TAG, p); } getApplication().dispatchActivitySaveInstanceState(this, outState); } 

clave ===> mFragments.saveAllState ()

si se confirma después de OnSaveInstanceState, el estado del fragmento no se guardará

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.