Pregunta

Leí en la documentación de Android que al configurar la propiedad launchMode de mi actividad en singleTop O al agregar el FLAG_ACTIVITY_SINGLE_TOP bandera a mi Intento, ese llamado startActivity(intent) reutilizaría una sola instancia de Actividad y me daría la Intención en el onNewIntent llamar de vuelta.Hice ambas cosas y onNewIntent nunca dispara y onCreate dispara cada vez.Los doctores también dicen que this.getIntent() devuelve la intención que se pasó por primera vez a la Actividad cuando se creó por primera vez.En onCreate estoy llamando getIntent y obtengo uno nuevo cada vez (estoy creando el objeto de intención en otra actividad y agregándole un extra... este extra debería ser el mismo cada vez si me devuelve el mismo objeto de intención).Todo esto me lleva a creer que mi actividad no actúa como un "único top", y no entiendo por qué.

Para agregar algunos antecedentes en caso de que simplemente me falte un paso requerido, aquí está mi declaración de Actividad en el manifiesto y el código que estoy usando para iniciar la actividad.La Actividad en sí no hace nada digno de mencionar con respecto a esto:

en AndroidManifest.xml:

    <activity
        android:name=".ArtistActivity"
        android:label="Artist"
        android:launchMode="singleTop">
    </activity>     

en mi actividad de llamada:

        Intent i = new Intent();
        i.putExtra(EXTRA_KEY_ARTIST, id);
        i.setClass(this, ArtistActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(i);
¿Fue útil?

Solución

¿Ha comprobado si onDestroy() se llama así? Esa es probablemente la razón por onCreate() se invoca cada vez que en lugar de onNewIntent(), que sólo se llama si la actividad ya existe.

Por ejemplo si deja su actividad a través de la tecla ATRÁS se destruye por defecto. Pero si vas más arriba en la pila de la actividad en otras actividades y desde allí llamar a su nuevo ArtistActivity.class se saltará onCreate() e ir directamente a onNewIntent(), debido a la actividad ya se ha creado y puesto que lo definió como singleTop Android no va a crear una nueva instancia de ella, pero tomar el uno que ya está ahí.

Lo que hago para ver lo que está pasando me implementar funciones ficticias para todos los diferentes estados de cada actividad, así que siempre ahora lo que está pasando:

@Override
public void onDestroy() {
    Log.i(TAG, "onDestroy()");
    super.onDestroy();
}

Lo mismo para onRestart(), onStart(), onResume(), onPause(), onDestroy()

Si el (BACK-botón) anterior no era su problema, la aplicación de estos maniquíes al menos ayudará a que la depuración sea un poco mejor.

Otros consejos

La respuesta aceptada no es del todo correcta.Si se llamó a onDestroy() anteriormente, entonces sí, siempre se llamaría a onCreate().Sin embargo, esta afirmación es incorrecta:"Si sube más en la pila de actividades hacia otras actividades y desde allí llama a su ArtistActivity.class nuevamente, omitirá onCreate() e irá directamente a onNewIntent()"

La sección "singleTop" de http://developer.android.com/guide/components/tasks-and-back-stack.html explica claramente cómo funciona (atención al texto en negrita a continuación;También probé esto mediante mi propia depuración):

"Por ejemplo, supongamos que la pila de tareas de una tarea consta de la actividad raíz A con las actividades B, C y D en la parte superior (la pila es A-B-C-D;D está en la cima).Llega un intent para una actividad de tipo D.Si D tiene el modo de inicio "estándar" predeterminado, se lanza una nueva instancia de la clase y la pila se convierte en A-B-C-D-D.Sin embargo, si el modo de inicio de D es "singleTop", la instancia existente de D recibe la intención a través de onNewIntent(), porque está en la parte superior de la pila; la pila sigue siendo A-B-C-D.Sin embargo, Si llega un intent para una actividad de tipo B, entonces se agrega una nueva instancia de B a la pila, incluso si su modo de inicio es "singleTop"."

En otras palabras, iniciar una actividad a través de SINGLE_TOP solo reutilizará la actividad existente si es ya en la parte superior de la pila.No funcionará si otra actividad en esa misma tarea está en la parte superior (por ejemplo, la actividad que ejecuta startActivity(SINGLE_TOP));En su lugar, se creará una nueva instancia.

Aquí hay dos formas de solucionar este problema. para que obtenga el comportamiento SINGLE_TOP que desea, cuyo propósito general es reutilizar una actividad existente, en lugar de crear una nueva...

primera manera (Como se describe en la sección de comentarios de la respuesta aceptada):Podrías agregar un modo de lanzamiento de "singleTask" a tu Actividad.Esto forzaría onNewIntent() porque singleTask significa que solo puede haber UNA instancia de una actividad particular en una tarea determinada.Sin embargo, esta es una solución algo complicada porque si tu aplicación necesita múltiples instancias de esa actividad en una situación particular (como lo hago yo con mi proyecto), estás jodido.

Segunda forma (mejor):En lugar de FLAG_ACTIVITY_SINGLE_TOP, utilice FLAG_ACTIVITY_REORDER_TO_FRONT.Esto reutilizará la instancia de actividad existente moviéndola a la parte superior de la pila (se llamará a onNewIntent() como se esperaba).

El objetivo principal de FLAG_ACTIVITY_SINGLE_TOP es evitar la creación de múltiples instancias de una Actividad.Por ejemplo, cuando esa actividad se puede iniciar a través de una intención que proviene de fuera de la tarea principal de su aplicación.Para el cambio interno entre actividades en mi aplicación, descubrí que FLAG_ACTIVITY_REORDER_TO_FRONT es generalmente lo que quiero.

Establecer este indicador en su intento:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top