La aplicación se reinicia por completo cuando se inicia al presionar el icono en el iniciador

80

Estoy en el proceso de intentar hacer una versión de lanzamiento de mi primera aplicación de Android para enviarla a algunos probadores. Sin embargo, me encontré con un problema. Cuando sale de la aplicación y luego vuelve a ingresarla iniciándola a través de su icono, reinicia toda la aplicación en lugar de regresar a su ubicación anterior. Esto ocurre incluso si vuelve a entrar inmediatamente después de salir. Sin embargo, no sucede si mantengo presionado el botón Inicio y lo lanzo a través de la lista de aplicaciones recientes.

He buscado en línea a otros que tienen este problema y hay algunos, pero nadie ha tenido una respuesta sólida de por qué les está sucediendo. Se ha sugerido en preguntas anteriores establecer el modo de lanzamiento en tarea única o instancia única en el archivo de manifiesto, pero eso no me ha ayudado y, además, por lo que tengo entendido, el comportamiento predeterminado para Android es volver al estado anterior de la tarea. en esta situación, así que no sé por qué necesitaría opciones de manifiesto especiales para hacer eso.

Lo más extraño de este problema es que si utilizo eclipse y el depurador para poner la aplicación en mi teléfono, este problema no ocurre. Ni siquiera necesito estar conectado al depurador, parece que mientras tenga una versión de depuración de la aplicación, el problema no ocurre. Pero si uso una versión de lanzamiento (la creo usando la opción de menú Herramientas de Android - Exportar paquete de aplicaciones firmado en Eclipse), el problema ocurre. Si alguien tiene alguna idea de lo que está causando esto, me encantaría escuchar sus pensamientos.

LayfieldK
fuente
2
Entonces, aparentemente, si reinicio el dispositivo en el que instalo la aplicación, este problema deja de existir. Ahora, eso es genial y todo, pero en el caso de mi aplicación, seguirá siendo extremadamente molesto para los usuarios si se comporta de esa manera antes de reiniciar el teléfono cuando la descargan.
LayfieldK
¿Puede proporcionar un seguimiento de pila o un registro?
Try TryAgain
2
No, solo sucede cuando uso una versión de lanzamiento de la aplicación, por lo que no tengo un seguimiento de pila ni un registro.
LayfieldK
3
Tuve el mismo problema, ¿alguna vez averiguaste la solución? o causa? o incluso poder recrear el comportamiento después de reiniciar el dispositivo? - por cierto, también encontré que detener la aplicación por la fuerza borra el comportamiento
kassim
2
Puede encontrar una respuesta válida para este problema aquí: stackoverflow.com/questions/19545889/…
Mythul

Respuestas:

59

Tuve el mismo problema con una aplicación y resolví este comportamiento agregando una bandera en "android:launchMode="singleTop""lugar de "android:launchMode="singleTask""en la <activity>declaración de su archivo AndroidManifest.xml. Espero que esto ayude a alguien.

cielo
fuente
3
Este enfoque es peligroso si queremos abrir la misma actividad dos veces con datos diferentes.
hkaraoglu
6
Si desea abrir la misma actividad con diferentes datos, puede manejar esto en onNewIntent ().
Tas
También descubrí que si elimino el android:launchModeatributo por completo, funcionó. No estoy seguro de si el valor predeterminado es "estándar", pero cualquier idea sería útil. Encontré esta gran explicación, pero es tarde, así que me parece un idioma extranjero en este momento: inthecheesefactory.com/blog/…
Joshua Pinter
Hola, ¿debo agregar android: launchMode = "singleTop" a todas mis actividades?
jmarkstar
Esto no funcionó en mi caso. En mi aplicación tengo una funcionalidad para crear y compartir el enlace de algo. Si la aplicación está en segundo plano y si el usuario hace clic en el enlace compartido, se abre una nueva instancia completa de la aplicación si mi launchMode está configurado en 'singleTop' o 'singleInstance'.
tech_human
33

Hasta ahora, descubrí que es un problema basado en cómo lo instalas en tu dispositivo real, específicamente:

  1. Si simplemente copia y pega el APK en el almacenamiento local de su dispositivo y lo instala desde el dispositivo, independientemente de si está firmado o sin firmar o tomado de la carpeta bin, muestra este comportamiento, la aplicación se reinicia desde el ícono del menú.

Si lo instala utilizando una de las siguientes opciones, este problema no aparece:

  1. Vaya a sdk / tools / usando una terminal o símbolo del sistema y luego escriba

    adb install <FILE PATH OF .APK FILE>
    

    En Linux, escriba:

    ./adb install <FILE PATH OF .APK FILE>
    
  2. Simplemente ejecute su proyecto desde Eclipse.

Me complacería saber si existe alguna forma posible de distribuir los APK correctos para las pruebas beta. Ya intenté exportar un APK firmado porque cuando copias y pegas un APK y lo instalas manualmente, muestra el comportamiento malicioso.

Actualizar:

Encontré una solución. Siga estos dos pasos:

  1. Establecer android:launchMode="singleTask" = truepara todas las actividades de su aplicación en AndroidMainifest.xml dentro de la etiqueta de actividad .
  2. Pon este código en la actividad de tu lanzador onCreate().

    if (!isTaskRoot())
    {
        final Intent intent = getIntent();
        final String intentAction = intent.getAction(); 
        if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
            finish();
            return;       
        }
    }
    

Este comportamiento es un error en Android. No es un caso especial.

Jayant Arora
fuente
2
No recomendaría esto. launchMode no solo debe establecerse. Tiene que tener un propósito, ya que puede causar un comportamiento extraño (hablar de las experiencias;))
Chico
Si su aplicación admite funciones como el bloqueo de PIN, debe tratarse con cuidado cuando desee configurar android: launchMode = "singleTask".
Logan Guo
10

Otra causa extraña, el reinicio ocurre solo cuando la aplicación se inició haciendo clic en "ABRIR" después de Copiar en el dispositivo - e - Instalar.

Prueba en OS8.1, sin launchMode en actividad.

ingrese la descripción de la imagen aquí

superusuario
fuente
¿Tienes alguna solución?
Abhay Koradiya
7

Puede usar launchMode como singleTop para la actividad del lanzador en AndroidManifest.xml

       <activity
        android:name="<YOUR_ACTIVITY>"
        android:label="@string/app_name"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
vasanth
fuente
5
 // To prevent launching another instance of app on clicking app icon 
        if (!isTaskRoot()
                && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
                && getIntent().getAction() != null
                && getIntent().getAction().equals(Intent.ACTION_MAIN)) {

            finish();
            return;
        }

escriba el código anterior en la actividad de su lanzador antes de llamar a setContentView. Esto solucionará el problema

Fathima km
fuente
3

Es el comportamiento predeterminado en Android. Para las compilaciones de depuración, funciona de manera diferente por alguna razón. Se puede resolver agregando android:launchMode="singleInstance"a la actividad, desea reiniciar después de iniciar desde el icono.

yak32
fuente
3

Agregue esto a su primera actividad:

if (!isTaskRoot()) {
        finish();
        return;
}     
super.onCreate(savedInstanceState);
Bolling
fuente
2
esto funcionó para mi caso, porque tiene una pantalla de presentación que maneja todos los puntos de entrada a una aplicación, por lo que si la pantalla de presentación ya lo hizo y se redirigió al lugar correcto la primera vez, no es necesario volver a hacerlo
Ahmed na
2

Intente usarlo android:alwaysRetainTaskStatecomo se muestra en el siguiente ejemplo:

<activity
    android:name="com.jsnider.timelineplanner.MainActivity"
    android:alwaysRetainTaskState="true"
    android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
jsnid00
fuente
2

Para mí, descubrí que había publicado erróneamente NoHistory = trueen mi atributo de actividad.

[Activity(NoHistory = true, ScreenOrientation = ScreenOrientation.Landscape)]

Esto impidió que la aplicación reanudara esta actividad y se reiniciara

Skaterhaz
fuente
1

Puede intentar configurar android:alwaysRetainTaskState="true"su actividad de iniciador en AndroidManifest.xml.

    <activity
        android:name=".YourMainActivity"
        android:alwaysRetainTaskState="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Para obtener más detalles, puede consultar https://developer.android.com/guide/topics/manifest/activity-element.html#always

Moven
fuente
1

Veo este problema en Android TV en 2019. ¿Existe una solución mejor para él? otro que

if (!isTaskRoot()) {
    finish();
}

Funciona, pero parece un truco más que la solución real.

Amit
fuente
0

Todas las soluciones anteriores no funcionaron de manera uniforme en todos mis dispositivos. Funcionó en algunos Samsung pero no en todos.

La causa del problema para mí fue instalar el APK manualmente.

Alberto M
fuente
0

Para mí, la solución fue agregar LaunchMode = LaunchMode.SingleTopa mi atributo Actividad sobre la Actividad principal:

/// <summary>
    /// The main activity of the application.
    /// </summary>
    [Activity(Label = "SilhuettePhone",
        Icon = "@drawable/icon",
        Theme = "@style/MainTheme",
        MainLauncher = true,
        ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
        ScreenOrientation = ScreenOrientation.Portrait,
        LaunchMode = LaunchMode.SingleTop,
        WindowSoftInputMode = SoftInput.AdjustResize)]
Calin Vlasin
fuente
-1

Cuando presiona el botón Atrás en Android, onDestroyse invoca el método (en lugar de presionar el botón Inicio, donde soloonPause() se invoca método).

Si necesita que su aplicación continúe donde la dejó, guarde el estado de la aplicación en su onDestroy()método y cargue ese estado en el onCreate()método.

Zoltán
fuente
1
Estoy presionando el botón de inicio para salir de la aplicación.
LayfieldK