IllegalStateException: no se Puede realizar esta acción después de onSaveInstanceState con ViewPager


Estoy recibiendo informes de usuarios de mi aplicación en el mercado, con la siguiente excepción:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyUp(Activity.java:2044)
at android.view.KeyEvent.dispatch(KeyEvent.java:2529)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2028)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4028)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)

Aparentemente tiene algo que ver con un FragmentManager, que no uso. El stacktrace no muestra ninguna de mis propias clases, por lo que no tengo idea de dónde ocurre esta excepción y cómo prevenirla.

Para el registro: Tengo un tabhost, y en cada pestaña hay un ActivityGroup cambiando entre Actividades.

Author: rds, 2011-09-28

26 answers

Por favor revisa mi respuesta aquí. Básicamente solo tenía que:

@Override
protected void onSaveInstanceState(Bundle outState) {
    //No call for super(). Bug on API Level > 11.
}

No haga la llamada a super() en el método saveInstanceState. Esto estaba arruinando las cosas...

Este es un bug conocido en el paquete de soporte.

Si necesita guardar la instancia y agregar algo a su outState Bundle puedes usar lo siguiente:

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
    super.onSaveInstanceState(outState);
}

Al final la solución adecuada fue (como se ve en los comentarios) usar:

transaction.commitAllowingStateLoss();

Al agregar o realizar el FragmentTransaction eso estaba causando el Exception.

 636
Author: Ovidiu Latcu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:15

Hay muchos problemas relacionados con un mensaje de error similar. Compruebe la segunda línea de esta traza de pila en particular. Esta excepción está específicamente relacionada con la llamada a FragmentManagerImpl.popBackStackImmediate.

Esta llamada al método, como popBackStack, siempre fallará con IllegalArgumentException si el estado de la sesión ya se ha guardado. Comprueba la fuente. No hay nada que puedas hacer para evitar que esta excepción sea lanzada.

  • Eliminar la llamada a super.onSaveInstanceState no ayudará.
  • Creando el fragmento con commitAllowingStateLoss no ayudará.

Así es como observé el problema:

  • Hay un formulario con un botón enviar.
  • Cuando se hace clic en el botón, se crea un diálogo y se inicia un proceso asincrónico.
  • El usuario hace clic en la tecla home antes de que finalice el proceso - se llama a onSaveInstanceState.
  • El proceso se completa, se realiza una devolución de llamada y se intenta popBackStackImmediate.
  • IllegalStateException se lanza.

Esto es lo que hice para resolverlo:{[15]]}

Como no es posible evitar el IllegalStateException en la devolución de llamada, capturarlo e ignorarlo.

try {
    activity.getSupportFragmentManager().popBackStackImmediate(name);
} catch (IllegalStateException ignored) {
    // There's no way to avoid getting this if saveInstanceState has already been called.
}

Esto es suficiente para evitar que la aplicación se bloquee. Pero ahora el usuario restaurará la aplicación y verá que el botón que pensó que había presionado no se ha presionado en absoluto (piensan). El fragmento de formulario todavía se muestra!

Para arreglar esto, cuando se crea el diálogo, haga algún estado para indicar que el proceso ha comenzado.

progressDialog.show(fragmentManager, TAG);
submitPressed = true;

Y guardar este estado en el paquete.

@Override
public void onSaveInstanceState(Bundle outState) {
    ...
    outState.putBoolean(SUBMIT_PRESSED, submitPressed);
}

No te olvides de carga de nuevo en onViewCreated

Luego, al reanudar, revertir los fragmentos si se intentó enviar previamente. Esto evita que el usuario regrese a lo que parece ser un formulario no enviado.

@Override
public void onResume() {
    super.onResume();
    if (submitPressed) {
        // no need to try-catch this, because we are not in a callback
        activity.getSupportFragmentManager().popBackStackImmediate(name);
        submitPressed = false;
    }
}
 99
Author: Synesso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-15 21:57:25

Comprueba si la actividad isFinishing() antes de mostrar el fragmento y presta atención a commitAllowingStateLoss().

Ejemplo:

if(!isFinishing()) {
FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            DummyFragment dummyFragment = DummyFragment.newInstance();
            ft.add(R.id.dummy_fragment_layout, dummyFragment);
            ft.commitAllowingStateLoss();
}
 47
Author: Naskov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-26 08:10:27

Aquí hay una solución diferente a este problema.

Usando una variable de miembro privado, puede establecer los datos devueltos como una intent que luego se puede procesar después de super.onResume ();

Así:

private Intent mOnActivityResultIntent = null; 

@Override
protected void onResume() {
    super.onResume();
    if(mOnActivityResultIntent != null){
        ... do things ...
        mOnActivityResultIntent = null;
    }
 }

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    if(data != null){
        mOnActivityResultIntent = data;
    }
}
 19
Author: Jed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-16 05:44:06

Es octubre de 2017, y Google hace que la biblioteca de soporte de Android con el componente de ciclo de vida de new things call. Proporciona alguna idea nueva para este' No puede realizar esta acción después deavaveinstancestate ' problema.

En resumen:

  • Usa el componente ciclo de vida para determinar si es el momento correcto para que aparezca tu fragmento.

Versión Más larga con explicar:

  • ¿Por qué surge este problema?

    Es porque usted está tratando de utilizar FragmentManager de su actividad(que va a contener su fragmento supongo?) para confirmar una transacción para su fragmento. Por lo general, esto parecería que está tratando de hacer alguna transacción para un fragmento que viene, mientras tanto, la actividad del host ya llama al método savedInstanceState (el usuario puede tocar el botón de inicio para que la actividad llame onStop(), en mi caso, es la razón)

    Por lo general, este problema no debería suceder always siempre tratamos de cargar fragmento en la actividad en el mismo comenzar, como el método onCreate() es un lugar perfecto para esto. Pero a veces esto sucede, especialmente cuando no puedes decidir qué fragmento cargarás en esa actividad, o estás tratando de cargar un fragmento desde un bloque AsyncTask (o cualquier cosa tomará un poco de tiempo). El tiempo, antes de que realmente ocurra la transacción de fragmentos, pero después del método onCreate() de la actividad, el usuario puede hacer cualquier cosa. Si el usuario presiona el botón de inicio, que activa el método onSavedInstanceState() de la actividad, habría un can not perform this action accidente.

    Si alguien quiere profundizar en este tema, le sugiero que eche un vistazo a este blog post. Se ve en lo profundo de la capa de código fuente y explica mucho al respecto. Además, da la razón por la que no debe usar el método commitAllowingStateLoss() para evitar este bloqueo (créame que no ofrece nada bueno para su código)

  • ¿Cómo arreglar esto?

    • ¿Debo usar el método commitAllowingStateLoss() para cargar el fragmento? No no debería;

    • ¿Debo anular el método onSaveInstanceState, ignorar el método super dentro de él? No deberías;

    • ¿Debería usar la actividad dentro de magical isFinishing, para comprobar si la actividad del host está en el momento adecuado para la transacción de fragmentos? Sí, esto parece la forma correcta de hacerlo.

  • Eche un vistazo a lo que el componente Lifecycle puede hacer.

    Básicamente, Google hace algunos implementación dentro de la clase AppCompatActivity (y varias otras clases base que debe usar en su proyecto), lo que facilita determinar el estado actual del ciclo de vida. Echa un vistazo a nuestro problema: ¿por qué sucedería este problema? Es porque hacemos algo en el momento equivocado. Así que tratamos de no hacerlo, y este problema desaparecerá.

    Codifico un poco para mi propio proyecto, esto es lo que hago usando LifeCycle. Codifico en Kotlin.

val hostActivity: AppCompatActivity? = null // the activity to host fragments. It's value should be properly initialized.

fun dispatchFragment(frag: Fragment) {
    hostActivity?.let {
       if(it.lifecyclecurrentState.isAtLeast(Lifecycle.State.RESUMED)){
           showFragment(frag)
       }
    }
}

private fun showFragment(frag: Fragment) {
    hostActivity?.let {
        Transaction.begin(it, R.id.frag_container)
                .show(frag)
                .commit()
    }

Como muestro arriba. Me comprobará el estado del ciclo de vida de la actividad del host. Con el componente de ciclo de vida dentro de la biblioteca de soporte, esto podría ser más específico. El código lifecyclecurrentState.isAtLeast(Lifecycle.State.RESUMED) significa, si el estado actual es al menos onResume, no más tarde de él? Lo que asegura que mi método no se ejecutará durante algún otro estado de vida(como onStop).

  • Está todo hecho?

    Por supuesto que no. El código que he mostrado dice una nueva forma de evitar que la aplicación se bloquee. Pero si va al estado de onStop, esa línea of code no hará cosas y por lo tanto no mostrará nada en su pantalla. Cuando los usuarios vuelvan a la aplicación, verán una pantalla vacía, que es la actividad de host vacía que no muestra fragmentos en absoluto. Es mala experiencia (sí, un poco mejor que un accidente).

    Así que aquí me gustaría que pudiera haber algo mejor: app no se bloqueará si llega a estado de vida más tarde que onResume, el método de transacción es consciente de estado de vida; además, la actividad intentará continuar para terminar esa transacción fragmento acción, después de que el usuario vuelva a nuestra aplicación.

    Añado algo más a este método:

class FragmentDispatcher(_host: FragmentActivity) : LifecycleObserver {
    private val hostActivity: FragmentActivity? = _host
    private val lifeCycle: Lifecycle? = _host.lifecycle
    private val profilePendingList = mutableListOf<BaseFragment>()

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun resume() {
        if (profilePendingList.isNotEmpty()) {
            showFragment(profilePendingList.last())
        }
    }

    fun dispatcherFragment(frag: BaseFragment) {
        if (lifeCycle?.currentState?.isAtLeast(Lifecycle.State.RESUMED) == true) {
            showFragment(frag)
        } else {
            profilePendingList.clear()
            profilePendingList.add(frag)
        }
    }

    private fun showFragment(frag: BaseFragment) {
        hostActivity?.let {
            Transaction.begin(it, R.id.frag_container)
                    .show(frag)
                    .commit()
        }
    }
}

Mantengo una lista dentro de esta clase dispatcher, para almacenar esos fragmentos no tengo oportunidad de terminar la acción de transacción. Y cuando el usuario regrese de la pantalla de inicio y encuentre que todavía hay un fragmento esperando a ser lanzado, irá al método resume() bajo la anotación @OnLifecycleEvent(Lifecycle.Event.ON_RESUME). Ahora creo que debería estar funcionando como esperaba.

 16
Author: Anthonyeef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-04 15:21:45

Solución Corta Y de trabajo:

Siga Sencillos Pasos

Pasos

Paso 1 : Anular el estado onSaveInstanceState en el fragmento respectivo. Y eliminar súper método de ella.

 @Override
public void onSaveInstanceState( Bundle outState ) {

}  

Paso 2: Uso fragmentTransaction.commitAllowingStateLoss( );

En lugar de fragmentTransaction.commit( ); mientras que las operaciones de fragmento.

 15
Author: Vinayak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-27 13:20:44

CUIDADO , usar transaction.commitAllowingStateLoss() podría resultar en una mala experiencia para el usuario. Para más información sobre por qué se lanza esta excepción, vea este post.

 11
Author: Eric Brandwein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-13 15:29:08

Encontré una solución sucia para este tipo de problema. Si usted todavía quiere mantener su ActivityGroups por cualquier razón (yo tenía razones de limitación de tiempo), usted acaba de implementar

public void onBackPressed() {}

En su Activity y haga algún código back allí. incluso si no hay tal Método en dispositivos más antiguos, este Método es llamado por los más nuevos.

 10
Author: saberrider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 13:10:59

No use commitAllowingStateLoss(), solo debe usarse para casos en los que está bien que el estado de la interfaz de usuario cambie inesperadamente en el usuario.

Https://developer.android.com/reference/android/app/FragmentTransaction.html#commitAllowingStateLoss()

Si la transacción ocurre en ChildFragmentManager de parentFragment, use parentFragment.isResume () fuera para comprobar en su lugar.

if (parentFragment.isResume()) {
    DummyFragment dummyFragment = DummyFragment.newInstance();
    transaction = childFragmentManager.BeginTransaction();
    trans.Replace(Resource.Id.fragmentContainer, startFragment);
}
 6
Author: Chandler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-20 05:19:57

Tuve un problema similar, el escenario era así:

  • Mi actividad es agregar/reemplazar fragmentos de lista.
  • Cada fragmento de lista tiene una referencia a la actividad, para notificar a la actividad cuando se hace clic en un elemento de lista (patrón de observador).
  • Cada fragmento de lista llama a setRetainInstance(true); en su método onCreate.

El método onCreate de la actividad fue así:

mMainFragment = (SelectionFragment) getSupportFragmentManager()
                .findFragmentByTag(MAIN_FRAGMENT_TAG);
        if (mMainFragment == null) {
            mMainFragment = new SelectionFragment();

            mMainFragment.setListAdapter(new ArrayAdapter<String>(this,
                    R.layout.item_main_menu, getResources().getStringArray(
                            R.array.main_menu)));
mMainFragment.setOnSelectionChangedListener(this);
            FragmentTransaction transaction = getSupportFragmentManager()
                    .beginTransaction();
            transaction.add(R.id.content, mMainFragment, MAIN_FRAGMENT_TAG);
            transaction.commit();
        }

La excepción fue lanzado porque cuando cambia la configuración (dispositivo girado), se crea la actividad, el fragmento principal se recupera del historial del administrador de fragmentos y, al mismo tiempo, el fragmento ya tiene una referencia ANTIGUA a la actividad destruida

Cambiar la implementación a esto resolvió el problema:

mMainFragment = (SelectionFragment) getSupportFragmentManager()
                .findFragmentByTag(MAIN_FRAGMENT_TAG);
        if (mMainFragment == null) {
            mMainFragment = new SelectionFragment();

            mMainFragment.setListAdapter(new ArrayAdapter<String>(this,
                    R.layout.item_main_menu, getResources().getStringArray(
                            R.array.main_menu)));
            FragmentTransaction transaction = getSupportFragmentManager()
                    .beginTransaction();
            transaction.add(R.id.content, mMainFragment, MAIN_FRAGMENT_TAG);
            transaction.commit();
        }
        mMainFragment.setOnSelectionChangedListener(this);

Debe configurar sus oyentes cada vez que se crea la actividad para evitar la situación en la que los fragmentos tienen referencias a antiguos instancias destruidas de la actividad.

 5
Author: Mina Samy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-18 12:28:37

Estaba recibiendo esta excepción cuando estaba presionando el botón atrás para cancelar el selector de intención en mi actividad de fragmento de mapa. Resolví esto reemplazando el código de onResume (donde inicializaba el fragmento) a onstart () y la aplicación funciona bien.Espero que ayude.

 3
Author: DCS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-14 11:35:34

Creo que usar transaction.commitAllowingStateLoss(); no es la mejor solución. Esta excepción se lanzará cuando cambie la configuración de la actividad y se llame a fragment onSavedInstanceState() y, a partir de entonces, su método de devolución de llamada asincrónica intente confirmar fragment.

La solución simple podría ser comprobar si la actividad está cambiando la configuración o no

Por ejemplo, comprobar isChangingConfigurations()

Es decir,

if(!isChangingConfigurations()) { //commit transaction. }

Checkout este enlace también

 2
Author: Amol Desai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-13 07:40:21

Si está haciendo algún FragmentTransaction en onActivityResult lo que puede hacer puede establecer algún valor booleano dentro de onActivityResult luego en onResume puede hacer su FragmentTransaction sobre la base del valor booleano. Por favor, consulte el siguiente código.

@Override
protected void onResume() {
    super.onResume;
    if(isSwitchFragment){
        isSwitchFragment=false;
        bottomNavigationView.getTabAt(POS_FEED).select();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == FilterActivity.FILTER_REQUEST_EVENT && data != null) {
        isSwitchFragment=true;
    }
}
 2
Author: anoopbryan2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-07 06:46:25

Posiblemente la solución más suave y simple que encontré en mi caso fue evitar sacar el fragmento ofensivo de la pila en respuesta al resultado de la actividad. Así que cambiando esta llamada en mi onActivityResult():

popMyFragmentAndMoveOn();

A esto:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    public void run() {
        popMyFragmentAndMoveOn();
    }
}

Ayudó en mi caso.

 1
Author: mojuba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-02 16:52:01

Cada vez que intente cargar un fragmento en su actividad, asegúrese de que la actividad está en reanudar y no se va a pausar state.In estado de pausa puede terminar perdiendo la operación de confirmación que se realiza.

Puede usar transaction.commitAllowingStateLoss () en lugar de transaction.commit () para cargar fragment

O

Crea un booleano y comprueba si la actividad no va a onpause

@Override
public void onResume() {
    super.onResume();
    mIsResumed = true;
}

@Override
public void onPause() {
    mIsResumed = false;
    super.onPause();
}

Luego, mientras se carga el fragmento de verificación

if(mIsResumed){
//load the your fragment
}
 1
Author: Anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-13 07:07:06

Con respecto a la gran respuesta de @Anthonyeef, aquí hay un código de ejemplo en Java:

private boolean shouldShowFragmentInOnResume;

private void someMethodThatShowsTheFragment() {

    if (this.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) {
        showFragment();
    } else {
        shouldShowFragmentInOnResume = true;
    }
}

private void showFragment() {
    //Your code here
}

@Override
protected void onResume() {
    super.onResume();

    if (shouldShowFragmentInOnResume) {
        shouldShowFragmentInOnResume = false;
        showFragment();
    }
}
 1
Author: MorZa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-17 12:10:03

Añade esto en tu actividad

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (outState.isEmpty()) {
        // Work-around for a pre-Android 4.2 bug
        outState.putBoolean("bug:fix", true);
    }
}
 0
Author: yifan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 12:35:06

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 sincrónica en lugar de llamar a commit() seguido de executePendingTransactions(). Como la documentación dice este enfoque aún mejor:

Llamar a commitNow es preferible a llamar a commit() seguido de executePendingTransactions (), ya que este último tendrá el efecto secundario de intentar confirmar todas las transacciones actualmente pendientes, independientemente de si ese es el comportamiento deseado o no.

 0
Author: Volodymyr Khodonovych,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-29 20:22:23

También he experimentado este problema y el problema ocurre cada vez que se cambia el contexto de su FragmentActivity (por ejemplo, se cambia la orientación de la pantalla, etc.).). Así que la mejor solución es actualizar el contexto desde su FragmentActivity.

 0
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-27 13:21:05

La excepción se lanza aquí (En FragmentActivity):

@Override
public void onBackPressed() {
    if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) {
        super.onBackPressed();
    }
}

En FragmentManager.popBackStatckImmediate()FragmentManager.checkStateLoss() se llama en primer lugar. Esa es la causa de IllegalStateException. See the implementation below:

private void checkStateLoss() {
    if (mStateSaved) { // Boom!
        throw new IllegalStateException(
                "Can not perform this action after onSaveInstanceState");
    }
    if (mNoTransactionsBecause != null) {
        throw new IllegalStateException(
                "Can not perform this action inside of " + mNoTransactionsBecause);
    }
}

Resuelvo este problema simplemente usando una bandera para marcar el estado actual de la actividad. Esta es mi solución:

public class MainActivity extends AppCompatActivity {
    /**
     * A flag that marks whether current Activity has saved its instance state
     */
    private boolean mHasSaveInstanceState;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        mHasSaveInstanceState = true;
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mHasSaveInstanceState = false;
    }

    @Override
    public void onBackPressed() {
        if (!mHasSaveInstanceState) {
            // avoid FragmentManager.checkStateLoss()'s throwing IllegalStateException
            super.onBackPressed();
        }
    }

}

 0
Author: Frost Lau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-07 06:19:20

Terminé creando un fragmento base y hago que todos los fragmentos en mi aplicación lo extiendan

public class BaseFragment extends Fragment {

    private boolean mStateSaved;

    @CallSuper
    @Override
    public void onSaveInstanceState(Bundle outState) {
        mStateSaved = true;
        super.onSaveInstanceState(outState);
    }

    /**
     * Version of {@link #show(FragmentManager, String)} that no-ops when an IllegalStateException
     * would otherwise occur.
     */
    public void showAllowingStateLoss(FragmentManager manager, String tag) {
        // API 26 added this convenient method
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (manager.isStateSaved()) {
                return;
            }
        }

        if (mStateSaved) {
            return;
        }

        show(manager, tag);
    }
}

Luego, cuando intento mostrar un fragmento, uso showAllowingStateLoss en lugar de show

Así:

MyFragment.newInstance()
.showAllowingStateLoss(getFragmentManager(), MY_FRAGMENT.TAG);

Llegué a esta solución de este PR: https://github.com/googlesamples/easypermissions/pull/170/files

 0
Author: Ahmad El-Melegy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-15 20:11:25

Otra posible solución, que no estoy seguro de si ayuda en todos los casos (origen aquí) :

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        final View rootView = findViewById(android.R.id.content);
        if (rootView != null) {
            rootView.cancelPendingInputEvents();
        }
    }
}
 0
Author: android developer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-09 08:26:14

Sé que hay una respuesta aceptada por @Ovidiu Latcu, pero después de algún tiempo, el error aún persiste.

@Override
protected void onSaveInstanceState(Bundle outState) {
     //No call for super(). Bug on API Level > 11.
}

Crashlytics sigue enviándome este extraño mensaje de error.

Sin embargo, el error ahora solo ocurre en la versión 7+ (Turrón) Mi solución fue usar commitAllowingStateLoss() en lugar de commit() en el FragmentTransaction.

Este post es útil para commitAllowingStateLoss() y nunca más tuvo un problema de fragmento.

Para resumirlo, el respuesta aceptada aquí podría funcionar en versiones de android pre Nougat.

Esto podría ahorrarle a alguien unas horas de búsqueda. felices codificaciones.

 0
Author: ralphgabb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-18 05:06:06

Tuve exactamente el mismo problema. Sucedió debido a la destrucción de la actividad anterior. cuando i respaldó la actividad anterior fue destruida. Lo pongo actividad base (MAL)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SpinnerCustom2.setFragmentManager(getSupportFragmentManager());
    onCreateDrawerActivity(savedInstanceState);
}

Lo puse en onStart era CORRECTO

@Override
protected void onStart() {
    super.onStart();
    SpinnerCustom2.setFragmentManager(getSupportFragmentManager());

}
 0
Author: Samet öztoprak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-13 06:13:16

Para evitar este problema, podemos usar El Componente de Arquitectura de navegación , que se introdujo en Google I/O 2018. El componente Arquitectura de navegación simplifica la implementación de la navegación en una aplicación Android.

 0
Author: Levon Petrosyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-22 12:09:38

Cortesía: Solución para IllegalStateException

Este problema me había molestado durante mucho tiempo, pero afortunadamente vine con una solución concreta para ello. Una explicación detallada de esto es aquí .

Usar commitAllowStateloss () podría evitar esta excepción, pero conduciría a la interfaz de usuario irregularities.So hasta ahora hemos entendido que IllegalStateException se encuentra cuando tratamos de confirmar un fragmento después de que se pierde el estado de la actividad, por lo que deberíamos retrasar el transacción hasta que el estado es restored.It se puede hacer simplemente así

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 desactivamos nuestra variable booleana isTansactionsafe. La idea es marcar trasnsaction seguro solo cuando la actividad está en primer plano por lo que no hay posibilidad de pérdida de estado.

/*
onPostResume is called only when the activity's state is completely restored. 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 se salvará de Ilegalstateexception, pero nuestras transacciones se perderán si se realizan después de que se mueva la actividad a background, algo así como commitAllowStateloss (). Para ayudar con eso tenemos variableansactionpending boolean variable

public void onPostResume(){
   super.onPostResume();
   isTransactionSafe=true;
/* Here after the activity is restored we check if there is any transaction pending from
the last restoration
*/
   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;
 }
}
 0
Author: IrshadKumail,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-30 17:35:19