2012-04-24 12 views
15

Sto provando a scrivere un test della strumentazione di attività Android che si arresta (onPause(), quindi onStop()) e riavvia l'attività corrente. Ho provatoCome interrompere e riavviare un'attività in un test di strumentazione Android?

activity.finish(); 
activity = getActivity(); 

... ma quello non sembra funzionare correttamente.

L'obiettivo del test è quello di affermare che i dati del modulo sono memorizzati durante il metodo onPause() e rileggere durante il metodo onStart(). Funziona quando lo fai manualmente, ma il test fallisce, da cui traggo la conclusione che activity.finish() sembra essere il modo sbagliato di fermare e riavviare un'attività.


Edit: Il mio problema principale sembra essere stato un problema di sincronizzazione. Dopo aver riavviato l'attività, il test runner non ha atteso il completamento di tutti i gestori di eventi. La seguente riga interrompe l'esecuzione di test fino a quando l'attività è inattivo:

getInstrumentation().waitForIdleSync() 

Oltre a questo, dare un'occhiata alla risposta accettata per maggiori informazioni preziose sul ciclo di vita.

+0

Che cosa sembra non funzionare correttamente? – yorkw

+0

@yorkw Ho aggiornato la domanda, grazie per il commento. –

+0

Cosa intendi quando dici "manualmente?" –

risposta

13

Chiamando (o innescare un cambiamento di orientamento dello schermo):

activity.finish(); // old activity instance is destroyed and shut down. 
activity = getActivity(); // new activity instance is launched and created. 

Causando l'attività passare attraverso l'intero ciclo di vita di ricreazione:

onPause() -> onStop() -> onDestroy() -> onCreate() 

Quello che vi serve è:

onPause() -> onStop() -> onRestart() 

Ho esposto il Instrumentation API di recente e ho trovato un sacco di attività interessanti Metodo e grilletto callActivityOnXXX(), la seguente riga singola del codice dovrebbe fare il difficile:

MyActivity myActivity = getActivity(); 
// make activity falling into restart phase: 
getInstrumentation().callActivityOnRestart(myActivity); 

Attività schema ciclo di vita citando guida ufficiale dev: enter image description here

+1

In realtà, ho già provato la prima soluzione, e non sembra funzionare come puoi vedere nella mia domanda. Ma forse hai ragione e il problema non è correlato ... Re il tuo secondo suggerimento, ci proverò più tardi ... –

+0

@DaniloBargen, controlla il mio aggiornamento. – yorkw

+0

che in realtà l'ha fatto, grazie mille! :) ti dispiacerebbe mettere questo in cima alla tua risposta per gli altri per trovare più facilmente? –

0

Forse u potrebbe cercare di salvare il nome della vostra attività, finitura ... e l'uso di riflessione per ottenere una nuova istanza della .class per il nuovo intento di creare ...

2

Un buon modo per testare gli eventi del ciclo di vita avviene attraverso le modifiche all'orientamento dello schermo. Nella mia esperienza è un modo conveniente per bombardare il pattern onPause/onStart.

+0

Idea interessante. Il problema con questo è che Android salva i dati del modulo per impostazione predefinita quando si esegue un cambio di orientamento dello schermo, in modo che non copra questo caso di test ... –

+0

Un cambio di orientamento dello schermo risultante completo Ciclo di vita dell'attività: ... -> onPause () -> onStop() -> onDestroy() -> onCreate() -> onStart() -> ..., che ha lo stesso comportamento di chiamare activity.finish(); activity = getActivity(); – yorkw

+0

@DaniloBargen Non credo che i dati del modulo vengano salvati di default quando un'attività viene distrutta. –

10

ho provato a chiamare .finish(), setActivity (Null), getActivity() e riavvia l'attività, ma per me non è stato ripristinato lo stato. Ho provato tutte le altre risposte su SO, e ogni altro metodo per farlo è stato trovato online, e nessuno di loro ha funzionato per me.Dopo molti esperimenti ho trovato i seguenti lavori (nb: richiede livello di API 11+):

getInstrumentation().runOnMainSync(new Runnable() { 
     @Override 
     public void run() { 
      activity.recreate(); 
     } 
    }); 
    setActivity(null); 
    activity = getActivity(); 

Quando faccio questo viene creata una nuova istanza di attività, e una nuova istanza del frammento avevo attaccato all'attività precedente nel test viene anche creato e sia l'attività che il frammento ripristinano il loro stato nel modo previsto.

Non so come funziona o perché funziona, ho raggiunto questa soluzione tramite prove ed errori e l'ho provato solo su un Nexus 4 con KitKat. Non posso garantire che simuli correttamente un'attività ricreativa, ma ha funzionato per i miei scopi.

Modifica: in un secondo momento ho capito come funziona. getActivity() funziona attraverso la registrazione di hook che ricevono nuove attività in fase di creazione, che catturano la nuova attività creata da activity.recreate(). setActivity(null) era necessario per cancellare il back-up cache interno getActivity, altrimenti restituirà quello vecchio e non ne cercherà uno nuovo.

È possibile vedere come funziona esaminando il codice sorgente per le varie classi di test case da cui si estende.

Problemi correlati