Relanzamiento del botón Actividad en Inicio, pero … solo la primera vez

La aplicación que estoy desarrollando tiene un comportamiento extraño la primera vez que se instala. Si el usuario se retira de la aplicación normalmente la primera vez, siempre se comportará como debería. Si el usuario usa el botón de inicio la primera vez después de instalar la aplicación, trata la aplicación como si debería volver a iniciar la pantalla de inicio e iniciar una nueva versión de una actividad en frente de la anterior.

Entonces, realmente hay dos asuntos a mano. Parece que no puedo resolver ambos.

  1. Mantenga la aplicación cerrada cuando se instala por primera vez cuando el usuario presiona el botón de inicio.
  2. Mantenga lanzadas varias versiones de la aplicación cuando lo haga (launchMode lo ayuda un poco, pero el primer componente todavía se activa).

No tengo el atributo launchMode en el archivo de manifiesto definido como cualquier cosa. Entonces, no debería haber ningún comportamiento extraño como resultado de esto. He experimentado ahora con el atributo launchmode de la aplicación para ver si puedo lograr que se comporte de la manera que se pretende, pero parece que hay algo más aquí que simplemente lanzar las actividades correctamente. No hay ninguna razón por la que una aplicación deba cerrarse por primera vez hasta donde yo pueda ver cuando se presiona el botón de inicio.

Tampoco utilizo onUserLeaveHint dentro de la aplicación. Tenía que estar seguro una vez más haciendo una búsqueda sobre el proyecto. Por lo tanto, no parece haber ningún cambio de botón de inicio en absoluto.

Incluso después de volver a encender el teléfono, el botón de inicio se comporta normalmente de nuevo. No estoy seguro de qué causa la instalación inicial para tratar el botón de inicio como un indicador para iniciar la aplicación desde cero.

Una vez que el usuario se retira de la aplicación por primera vez, el problema se resuelve permanentemente. ¿Alguna idea de dónde debería mirar?

Recientemente se ha realizado una búsqueda dentro de la aplicación para ver si tal vez solo se desencadena debido a un componente onUpgrade() del método de la base de datos SQLite que causa un comportamiento extraño.

 @Override public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) { if (newVersion > oldVersion) { } } 

O en otra ubicación que podría desencadenarse con una actualización del archivo de manifiesto si pasaba una versión más reciente de la APK junto a un dispositivo que tenía una versión que ya era una más baja que la actual. Sin embargo, nada en esta parte del código me lleva a creer que debería afectar algo relacionado con la secuencia de lanzamiento.

El archivo de manifiesto (con los nombres modificados) se proporciona a continuación para lo que se está utilizando actualmente en la aplicación.

                                               

Bienvenido a la lista cada vez mayor de usuarios que han sido mordidos por este.

Este es un error conocido y antiguo de Android . en la forma en que las aplicaciones se inician por primera vez desde el instalador, el navegador web y mediante IDE (IntelliJ, Eclipse, etc.). Vea estos problemas presentados hace mucho tiempo relacionados con el problema:

http://code.google.com/p/android/issues/detail?id=2373

http://code.google.com/p/android/issues/detail?id=26658

Todavía está roto y no puedes evitar que esto suceda. Lo único que puede hacer es detectar cuándo Android ha lanzado una segunda instancia de su actividad raíz en una tarea existente . Puede hacer esto colocando este código en onCreate() de su actividad raíz:

 if (!isTaskRoot()) { // Android launched another instance of the root activity into an existing task // so just quietly finish and go away, dropping the user back into the activity // at the top of the stack (ie: the last state of this task) finish(); return; } 

Por qué esto se está comportando, no hay pista. Pero sé que el Launcher personalizado tiene un conjunto específico de launchModes .

Por ejemplo, el ADW.Launcher:

 android:clearTaskOnLaunch="true" android:launchMode="singleTask" 

Aplicación de inicio en los ejemplos de Android SDK: android-sdk\samples\android-16\Home\AndroidManifest.xml

 android:launchMode="singleInstance" 

Para citar a CommonsWare: ¿Cómo prevenir la actividad de reinicio de aplicaciones de iniciador de inicio personalizado?

Voy por la aplicación de muestra Home del SDK, que usa singleInstance. Curiosamente, los lanzadores AOSP usan singleTask

Parece que el problema está causado por las diferentes instancias de la aplicación. Probablemente, la primera instancia se inicia bajo la tarea del instalador y la segunda se encuentra bajo su propia tarea, cuando el usuario hace clic en el icono de la aplicación. Parece que el usuario reanuda la aplicación, pero en realidad la vuelve a lanzar en este momento.

Si desea que su aplicación se ejecute solo en su propia tarea, una posible forma es agregar

 android:allowTaskReparenting="true" 

al nivel de aplicación de su AndroidManifest. Una vez que se hace clic en el icono de la aplicación por primera vez después de la instalación, su aplicación se moverá a la tarea separada.