2012-06-28 9 views
12

Ho un'applicazione in cui il punto di ingresso è diciamo un "login/splash"Activity, in cui è necessario precaricare i dati freschi dal server. Questo SplashActivity è dichiarato come:Riavvio dell'applicazione - Punto di immissione attività

<action android:name="android.intent.action.MAIN" /> 
<category android:name="android.intent.category.LAUNCHER" /> 

nel mio AndroidManifest.xml, dopo che i dati viene caricato, continuo alcuni dati sulla mia classe personalizzata Application e procedere al mio MainActivity.

Mi aspetto, che dopo la mia Application viene fermato dal sistema operativo o dall'utente (tramite Forza Stop), e poi di riavviare da parte dell'utente, il punto di ingresso della mia candidatura per essere SplashActivity nuovo MA il sistema salta lo SplashActivity e visualizza MainActivity.

DOMANDA: è questo il comportamento previsto? Se l'intero processo viene interrotto, la mia applicazione non dovrebbe essere avviata con SplashActivity? Questo può essere realizzato?

+0

puoi impostare android: noHistory = "true" nel tag attività nel file manifest – rajpara

+0

AFAIK, la tua domanda è errata, l'app forzata verrà sempre avviata dall'attività di avvio principale. – MKJParekh

risposta

24

In realtà, ci sono diversi problemi che sono disciplinati da questa domanda e alcune delle risposte ad esso:


Per rispondere alla tua domanda iniziale: "Sì, questo è il comportamento previsto".

Android considera ogni attività come un'entità autonoma separata. Android ricorda lo stato delle attività nello stack delle attività e non ha alcun problema ad uccidere il tuo processo (che contiene tutte le tue attività) ogni volta che lo desidera, perché "sa" che può sempre ricostruire le tue attività ogni volta che è necessario. Questo concetto, ovviamente, si interrompe quando si dispone di un'applicazione complessa in cui si hanno dipendenze tra le attività e/o si dispone di dati globali memorizzati in una classe Application (o un posto statico/singleton simile).

Quando Android uccide il processo si ricorda l'attività più in alto nel compito e quando l'utente ritorna al compito che ricrea il processo e poi ricrea solo l'attività più in alto nel compito. Nel tuo caso, MainActivity.

Per fare un esempio, se il vostro stack compito è simile al seguente:

StartActivity -> ActivityB -> ActivityC -> ActivityD 

e il vostro compito va al fondo e Android uccide il processo, quando verranno ricreati l'utente torna l'attività soltanto ActivityD. Una volta terminato lo ActivityD, Android ricreerà quindi ActivityC. Una volta terminato lo ActivityC, Android ricreerà ActivityB, ecc.In breve, lo stack completo è non ricreato quando l'utente riprende l'attività.

Non esiste una combinazione di impostazioni manifest o di Intent flags che ti consentano di ottenere il comportamento desiderato. Sarebbe bello se Android offrisse qualcosa del genere, ma al momento no.


È possibile determinare se il processo è stato riavviato utilizzando uno statico (classe) variabile booleana nella classe Application-derivato (o in qualsiasi altra classe). Questa variabile avrà sempre il valore false quando il processo viene riavviato e sarà quindi possibile controllare lo stato della variabile da qualsiasi posizione e reinizializzare (ricaricare i dati) se necessario. Quindi imposta la variabile su true. Rimarrà true fino a quando il processo non viene ucciso e ricreato, anche se tutte le attività sono terminate. In questo modo è possibile inizializzare solo quando necessario.

È inoltre possibile utilizzare questo come indicatore per riavviare l'applicazione da SplashScreen. Quindi, in tutte le vostre attività, in onCreate(), è possibile verificare lo stato di questa variabile booleana e se l'applicazione è stata riavviata si può semplicemente reindirizzare al SplashScreen in questo modo:

Intent intent = new Intent(this, SplashScreen.class); 
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent); 

Questo si concluderà tutte le attività del attività e riavviare il SplashScreen nella radice dell'attività.


successivo, se si vuole evitare di dover scaricare i dati ogni volta che l'utente torna l'applicazione (quando era in background e successivamente ucciso dai AndroidOS), è necessario memorizzare i dati che si scarica in l'area della cache privata e utilizzarla al riavvio dell'applicazione. Ciò impedisce di dover scaricare ripetutamente i dati se il processo viene ucciso e riavviato.


Un altro modo per risolvere questo problema è caricare i dati in un servizio. Se hai un Service in esecuzione nel tuo processo, Android ha meno probabilità di uccidere il tuo processo. Devi solo assicurarti di spegnere il tuo Service quando l'utente ha finito con la tua applicazione.


Mi rendo conto che questa risposta è prolissa. Spero che tu possa ottenere qualcosa da esso.

+0

sì. grazie per il tuo tempo. Ero davvero convinto che una volta che il processo è stato arrestato dal sistema operativo, l'applicazione verrà riavviata dal punto di ingresso ... perché questo è ciò che accade quando ARRESTIAMO ... tramite DDMS o Impostazioni-> Applicazioni. –

+2

no, in realtà non è vero. Quello che succede quando lo fermi è questo: il debugger invia un segnale al processo per ucciderlo, quindi il processo muore. Android vede questo e dice "Oh, c'è un'attività maleducata in quell'applicazione che ha causato la sua morte. Quindi riavvierò quella procedura per l'utente, ma prima di farlo, rimuoverò quell'attività che si comporta male dallo stack ". Quindi quello che vedi è il riavvio del processo con la tua attività di root. –

+0

grazie mille a tutti e due ... Ho trascorso alcuni giorni su un problema simile http: //stackoverflow.com/questions/11190469/android-app-crashes-suddenly-while-running ... Domanda e la tua risposta davvero aiutato molto ... – aProgrammer

0

si può fare in questo modo:

1.SplashActivity inizierà senza dubbio ogni volta.

2. Scarica i dati e salvare il controllo (booleano) indica il carico è fatto previously.You può utilizzare SharedPreferences.

3. Controllare la condizione la volta successiva e avviare immediatamente il MainActivity.

+0

sì ma una volta impostato il mio "controllo" su vero, quando lo imposto su "falso"? –

+0

riguardo a "1", come puoi argomentare che Splash inizierà ogni volta? qualcuno sta avendo lo stesso problema, dopo il riavvio dell'applicazione http://stackoverflow.com/questions/11190469/android-app-crashes-suddenly-while-running/11242705#11242705 –

+0

devi scaricare i dati ogni volta che l'app inizia? –