2011-07-13 13 views
5

Tengo una aplicación de Android con una serie de actividades. La actividad incorrecta se inicia a veces.Android - La actividad incorrecta a veces comienza

Normalmente, una subclase de aplicación se inicia, a continuación, iniciar la actividad (StartAct ... android: name = "android.intent.action.MAIN", android: name = "android.intent.category.LAUNCHER") funciona un poco y luego inicia InitializeActivity. Esto hace un poco de trabajo y luego dispara mi actividad de visualización principal (MainAct). Las dos primeras actividades realizan una inicialización esencial, incluida la configuración de un indicador estático "isInitialized" justo antes de iniciarse la intención para el MainAct.

Las actividades se inician con startActivity() con un propósito específico (... activity.class especificado) y call finish() después de startActivity().

Sin embargo, esto es lo que a veces sucede, y no sé por qué ...

En resumen, la aplicación se mata y cuando se pulsa el icono para iniciarlo, se salta directamente a la tercera (MainAct) actividad. Esto hace que la aplicación para detectar un error (IsInitialized bandera es falsa) y detener:

  • lanzar la aplicación normalmente con el icono:
  • ... subclase aplicación se inicia, además de fuegos en algunos subprocesos de trabajo
  • ... startActivity carreras, y luego se dispara InitializeActivity y termina
  • ... InitializeActivity carreras, a continuación, establece IsInitialized y comienza MainAct y acabados
  • ... MainAct se inicia, se ejecuta okay
  • ... botón de inicio es golpeado y Angry Birds se ejecuta
  • ... MainAct registros onPause, luego onStop.
  • ... Subprocesos de trabajo propiedad de la subclase Aplicación continúan haciendo cosas periódicamente y registrando.
  • Después de 25 minutos, toda la aplicación se destruye de repente. Esta observación se basa en extremo thhe de la actividad maderera,
  • El tiempo pasa
  • botón Inicio golpeado
  • icono del iniciador se presiona para la aplicación
  • Aplicación subclase onCreate se llama y devuelve
  • * Se llama a MainAct.onCreate!(Sin StartAct, sin InitializeActivity) *

¿Qué me falta?

Nota: el indicador de inicialización se agregó debido a este problema. Se establece en el único lugar del código que inicia la actividad principal y solo se marca en Crear en la actividad principal.

[por solicitud] Archivo de manifiesto (ligeramente redactado). Tenga en cuenta que el servicio aquí no se usa actualmente.

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="xxx.yyy.zzz" 
    android:versionCode="1" android:versionName="1.0.1"> 
    <application 
    android:icon="@drawable/icon_nondistr" 
    android:label="@string/app_name" 
    android:name=".app.MainApp" 
    android:debuggable="true"> 
    <activity 
     android:label="@string/app_name" 
     android:name=".app.StartAct" android:theme="@android:style/Theme.NoTitleBar"> 
     <intent-filter> 
     <action 
      android:name="android.intent.action.MAIN" /> 
     <category 
      android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity 
     android:label="Html" 
     android:name=".app.HtmlDisplayAct"/> 
    <activity 
     android:label="Init" 
     android:configChanges="orientation" 
     android:name=".app.InitializeActivity" android:theme="@android:style/Theme.NoTitleBar"/> 
    <activity 
     android:label="MyPrefs" 
     android:name=".app.PrefsAct" /> 
    <activity 
     android:label="@string/app_name" 
     android:theme="@android:style/Theme.NoTitleBar" 
     android:name=".app.MainAct"> 
    </activity> 
    <service 
     android:name=".app.svcs.DataGetterService" /> 
    </application> 
    <uses-sdk android:minSdkVersion="4"/> 
    <uses-permission 
    android:name="android.permission.INTERNET" /> 
    <uses-permission 
    android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission 
    android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission 
    android:name="com.android.vending.CHECK_LICENSE" /> 
    <uses-feature 
    android:name="android.hardware.location.network" 
    android:required="false" /> 
</manifest> 
+0

puede mostrar el archivo de manifiesto ... costuras, como un problema por allá .. – Dinash

+0

añadido por su solicitud. – Mesocyclone

+0

Esta es una publicación muy antigua, pero me alegro de que la hayas publicado y me alegro de haberla encontrado. De lo contrario, no podría creer que realmente estaba experimentando lo que Android estaba haciendo con mi aplicación. Lamentablemente, la única respuesta es bastante problemática: tendré que agregar el código kludgy a aproximadamente 20 clases de Actividad para detectar todos los casos posibles. ¿Alguna vez encontró una mejor solución? – RenniePet

Respuesta

2

El hecho de que la aplicación falle por falta de memoria debe ser transparente para los usuarios. Es por eso que cuando se mata la aplicación, Android recuerda cuál fue la última actividad que se ejecutó en esta aplicación y crea directamente esta actividad cuando el usuario regresa a la aplicación.

Tal vez podría hacer algo en el método de su Application (o de su MainAct) para asegurarse de que todo está inicializado correctamente onCreate().

Por cierto, a menos que realmente lo necesite, no debería tener hilos de trabajo trabajando cuando el usuario no está utilizando su aplicación. Dependiendo de lo que haga, esto podría agotar la batería rápidamente o hacer que el usuario piense que podría agotar la batería rápidamente (lo que es peor, ¡porque el usuario desinstalará su aplicación!)

También podría hacer que la aplicación termine cada actividad cuando el usuario está saliendo de la aplicación,

+0

Parte de la funcionalidad es realizar trabajos periódicos en segundo plano, por lo que necesito hilos de trabajo en alguna parte (podría estar en un servicio, pero no es así). Si bien podría tener onCreate() asegurar la inicialización, esto no sería fácil (durante la inicialización, tengo una actividad diferente para poder mostrar cosas sobre la inicialización). No pude encontrar en los documentos que Android haga este comportamiento o no lo habría preguntado. ¿Estás seguro de esto? Tenga en cuenta que no es transparente para el usuario: el usuario debe presionar nuevamente el ícono de actividad para reiniciarlo. El solo hecho de hacer una copia de seguridad de la pila no inicia la aplicación. Tks. – Mesocyclone

+0

Si coloca sus hilos de trabajo en un servicio, probablemente su aplicación no muera y no tendrá el problema. No estoy completamente seguro de que lo que dije sea correcto, pero el documento dice que _Si una actividad se detiene o detiene, el sistema puede eliminar la actividad de la memoria pidiéndole que termine o simplemente eliminando el proceso. Cuando se muestre de nuevo al usuario, debe reiniciarse completamente y restablecerse a su estado anterior. [Aquí] (http://developer.android.com/reference/android/app/Activity.html), no estoy seguro de qué significa. –

+0

Otra idea, no sé si funcionaría, sería declarar 'MainAct' como la actividad principal (cuyo icono se muestra en el iniciador) y hacer que' onCreate() 'de la aplicación ejecute' StartActivity' (quizás tenga que esperar en 'MainAct' para que se complete la inicialización). –

0

Esto es realmente un caso de "añadir insulto a la lesión" - primero Android mata mi aplicación increíble, y luego, cuando el usuario reinicia mi aplicación Android intenta ser "útil" al lanzar la actividad incorrecta, haciendo que mi aplicación se cuelgue. Suspiro.

Aquí está mi solución muy kludgy para contrarrestar la utilidad de Android. Mi aplicación requiere que StartActivity sea la primera actividad, por lo que para todas las demás actividades agrego una línea al método onCreate(). Por ejemplo:

public class HelpActivity extends AppCompatActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     if (StaticMethods.switchToStartActivityIfNecessary(this)) return; // <- this is the magic line 

     ... 

    } 

    ... 

} 

Para hacer este trabajo que he añadido una variable de cambio a mi clase de aplicación:

public class OutBackClientApplication extends Application { 

    ... 

    // Switch to indicate if StartActivity has been started. 
    // Values: -1 = StartActity has never been started or this is first invocation. 
    //   0 = normal situation, StartActivity has been run at least once. 
    private int _startActivityStatus = -1; 

    public int getStartActivityStatus() { return _startActivityStatus; } 

    public void setStartActivityStatus(int startActivityStatus) { 
     _startActivityStatus = startActivityStatus; 
    } 

    ... 

} 

Y tengo una clase llamada StaticMethods, que incluye el siguiente método:

public class StaticMethods { 

    /** 
    * Method to test for the problematic situation where Android has previously killed this app, and 
    * then when the user restarts the app Android tries to be helpful by restarting the activity 
    * that was in the foreground when it killed the app, instead of starting the activity specified 
    * in the manifest as the launch activity. See here: 
    * http://stackoverflow.com/questions/6673271/android-wrong-activity-sometimes-starts 
    * 
    * The following line should be added to the onCreate() method of every Activity, except for 
    * StartActivity, of course: 
    * 
    * if (StaticMethods.switchToStartActivityIfNecessary(this)) return; 
    */ 
    public static boolean switchToStartActivityIfNecessary(Activity currentActivity) { 

     OutBackClientApplication outBackClientApplication = 
             (OutBackClientApplication) currentActivity.getApplication(); 

     if (outBackClientApplication.getStartActivityStatus() == -1) { 
     currentActivity.startActivity(new Intent(currentActivity, StartActivity.class)); 
     currentActivity.finish(); 
     return true; 
     } 
     return false; 
    } 

} 

Por último, cuando se inicia startActivity que necesita para restablecer el interruptor:

public class StartActivity extends AppCompatActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ((OutBackClientApplication) getApplication()).setStartActivityStatus(0); 

     ... 

    } 

    ... 

} 

Todo eso, sólo para contrarrestar "amabilidad" de Android ...

Cuestiones relacionadas