Bloqueo en transiciones de actividad con SharedElement

4 minutos de lectura

Avatar de usuario de OferM
OfertaM

Estoy usando transiciones de actividad de un ViewPager (en la actividad de llamada) con un elemento compartido y transiciones de contenido también. Recibo este bloqueo cuando vuelvo a ingresar a la actividad de llamadas:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.ResultReceiver.send(int, android.os.Bundle)' on a null object reference
  at android.app.EnterTransitionCoordinator.sendSharedElementDestination(EnterTransitionCoordinator.java:199)
  at android.app.EnterTransitionCoordinator.viewsReady(EnterTransitionCoordinator.java:123)
  at android.app.EnterTransitionCoordinator$2.onPreDraw(EnterTransitionCoordinator.java:148)
  at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:895)
  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2153)
  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1180)
  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6558)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
  at android.view.Choreographer.doCallbacks(Choreographer.java:590)
  at android.view.Choreographer.doFrame(Choreographer.java:560)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:145)
  at android.app.ActivityThread.main(ActivityThread.java:5832)
  at java.lang.reflect.Method.invoke(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)

Además, una vez que regresa, la pantalla comienza a parpadear continuamente con una pantalla blanca que se enciende y se apaga.

Aquí están mis banderas de transición:

<item name="android:windowContentTransitions">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowAllowReturnTransitionOverlap">false</item>

Intenté configurar las transiciones Entrar/Salir tanto en la actividad de Llamada como en la de Llamada, pero no tuve suerte.

  • Vaya, eso es nuevo. Idealmente, presentaría un error en esto con una aplicación que pueda reproducirlo. Parece que la actividad existente estableció el ResultReceiver en nulo de alguna manera. Si no puede resolver esto de otra manera, puede usar finish() en lugar de finishAfterTransition() para evitar la transición de actividad, pero es bastante extraño. ¿Es posible que la actividad de salida se elimine a medida que se inicia la actividad de reingreso?

    – Jorge Monte

    11 de diciembre de 2015 a las 3:10


  • @GeorgeMount no lo creo. Si A es la actividad de llamada y B es la actividad de llamada, mis registros al ingresar a B son los siguientes: A: onPause B: onCreate B: onStart B: onResume B: onSaveInstanceState A: onStop

    – OferM

    13 de diciembre de 2015 a las 8:05


  • Y luego, al volver a ingresar, idealmente debería ser: A: onStart (el bloqueo está aquí) B: onPause A: onResume B: onStop B: onDestroy

    – OferM

    13 de diciembre de 2015 a las 9:06

  • También noté que la transición de reingreso funciona para los primeros 2 fragmentos en ViewPager y se bloquea constantemente para el resto de los elementos. El ViewPager siempre contiene el mismo fragmento, por lo que no es un problema de fragmento específico.

    – OferM

    13 de diciembre de 2015 a las 9:31

  • Noté el mismo problema que ocurre a veces en mi aplicación al pasar de la pantalla de detalles a la pantalla de colección con un visor y ambas pantallas tienen una vista de imagen compartida que muestra la animación de transición.

    – Ankur

    30 de diciembre de 2015 a las 9:12

Avatar de usuario de FRIST_008
FRIS_008

Intenta obtener un fragmento de FragmentManager:

fragmentManager.findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + position)

Si el fragmento es nulo, intente crear un nuevo fragmento.

Avatar de usuario de Jivanlal Bhavsar
Jivanlal Bhavsar

Las transiciones de actividad con elementos compartidos a veces pueden provocar fallas debido a varias razones. Aquí hay algunas causas comunes de bloqueos y cómo evitarlos:

Problemas de tiempo: asegúrese de que los elementos compartidos tengan el tamaño y la disposición adecuados antes de que comience la transición. Retrasar el inicio de la transición hasta después de que los elementos compartidos se hayan inicializado por completo puede evitar bloqueos.

Nombres incoherentes: si utiliza transiciones de elementos compartidos entre actividades, asegúrese de que los nombres de los elementos compartidos en ambas actividades sean iguales. Los nombres que no coinciden pueden provocar un bloqueo.

Uso incorrecto de View.setTransitionName(): al usar transiciones de elementos compartidos, es importante establecer un nombre de transición único para cada elemento compartido. Si dos elementos compartidos tienen el mismo nombre de transición, puede producirse un bloqueo.

OutOfMemoryErrors: las imágenes grandes o los mapas de bits utilizados como elementos compartidos pueden causar OutOfMemoryErrors, lo que provoca un bloqueo. Para evitar esto, asegúrese de cambiar el tamaño de las imágenes o mapas de bits a un tamaño más pequeño antes de usarlos como elementos compartidos.

Transición faltante en XML: si la transición entre las dos actividades no está definida en el XML, puede producirse un bloqueo. Asegúrese de que la transición esté definida correctamente en el XML y que se esté utilizando la transición correcta para los elementos compartidos.

Aquí hay un mejor ejemplo de cómo evitar problemas de tiempo al usar elementos compartidos:

private void startActivityWithSharedElement(Intent intent) {
    final ImageView sharedImageView = findViewById(R.id.shared_image_view);

    sharedImageView.getViewTreeObserver().addOnPreDrawListener(

        new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {

         sharedImageView.getViewTreeObserver().removeOnPreDrawListener(this);
         startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(
                                MainActivity.this, sharedImageView, "shared_image").toBundle());
                return true;
            }
        });
}

¿Ha sido útil esta solución?