Domanda

Ho letto in Android documentazione che impostando la mia Attività launchMode proprietà singleTop O aggiungendo il FLAG_ACTIVITY_SINGLE_TOP bandiera a mio Intento, che chiamata startActivity(intent) vorresti riutilizzare una singola istanza di Attività e mi danno l'Intento del onNewIntent richiamata.Ho fatto entrambe le cose, e onNewIntent non viene generato e onCreate si attiva ogni volta.I documenti anche dire che this.getIntent() restituisce l'intento che era passato prima per l'Attività quando è stata creata.In onCreate Sto chiamando getIntent e sto ottenendo uno nuovo ogni volta (sto creando l'intento oggetto in un'altra attività e l'aggiunta di un extra...questa extra dovrebbe essere lo stesso ogni volta che se ne stava tornando a me stesso intento oggetto).Tutto questo mi porta a credere che la mia attività non è di agire come un "unica", e non capisco perché.

Per aggiungere un po ' di sfondo nel caso sto semplicemente manca un passaggio obbligatorio, ecco la mia Attività dichiarazione nel manifesto e il codice che sto usando per avviare l'attività.L'Attività stessa non fare nulla vale la pena di menzionare in riferimento a questa:

in AndroidManifest.xml:

    <activity
        android:name=".ArtistActivity"
        android:label="Artist"
        android:launchMode="singleTop">
    </activity>     

nella mia vocazione Attività:

        Intent i = new Intent();
        i.putExtra(EXTRA_KEY_ARTIST, id);
        i.setClass(this, ArtistActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(i);
È stato utile?

Soluzione

Hai controllato se onDestroy() è stato chiamato così? Questo è probabilmente il motivo per cui onCreate() viene invocato ogni volta invece di onNewIntent(), che sarebbe chiamato solo se l'attività è già esistente.

Per esempio, se si lascia la vostra attività tramite il pulsante INDIETRO viene distrutta per impostazione predefinita. Ma se si va più in alto sullo stack di attività in altre attività e da lì chiamare il ArtistActivity.class di nuovo si salta onCreate() e passare direttamente alla onNewIntent(), in quanto l'attività è già stato creato e dal momento che è stato definito come singleTop Android non creerà un nuova istanza di esso, ma prendere quello che è già in giro.

Quello che faccio per vedere cosa sta succedendo ho implementare funzioni fittizi per tutti i diversi stati di ogni attività così ho sempre ora che cosa sta succedendo:

@Override
public void onDestroy() {
    Log.i(TAG, "onDestroy()");
    super.onDestroy();
}

Lo stesso vale per onRestart(), onStart(), onResume(), onPause(), onDestroy()

Se la (BACK-tasto) non era il problema, l'attuazione di tali manichini saranno almeno aiutare debug di esso un po 'meglio.

Altri suggerimenti

Accettato risposta non è del tutto corretto.Se onDestroy() è stato chiamato in precedenza, quindi sì, onCreate() dovrebbe sempre essere chiamato.Tuttavia, questa affermazione è sbagliata:"Se si va più in alto sull'attività stack in altre attività e da lì chiamare il ArtistActivity.class di nuovo si passa onCreate() e passare direttamente al onNewIntent()"

Il "singleTop" sezione di http://developer.android.com/guide/components/tasks-and-back-stack.html spiega chiaramente come funziona (attenzione per il testo in grassetto di seguito;Ho anche provato con la mia debug):

"Per esempio, supponiamo di un'attività di back stack consiste principale attività con attività di B, C, e D (o deila pila è A-B-C-D;D è in cima).Un intento che arriva per un'attività di tipo D.Se D è il valore di default "standard"modalità di avvio, una nuova istanza della classe viene lanciato e la pila diventa A-B-C-D-D.Tuttavia, se D modalità di lancio è "singleTop", l'istanza esistente di D riceve l'intento, attraverso onNewIntent(), perchè è alla cima dello stack—stack rimane A-B-C-D.Tuttavia, se l'intento arriva un'attività di tipo B, quindi una nuova istanza di B è aggiunto alla pila, anche se la sua modalità di lancio è "singleTop"."

In altre parole, l'avvio di un'attività attraverso SINGLE_TOP solo riutilizzare l'attività esistente se è già in cima alla pila.Non lavoro se un'altra attività nello stesso compito, è il top (per esempio, l'attività è l'esecuzione di startActivity(SINGLE_TOP));una nuova istanza verrà creata, invece.

Qui ci sono due modi per risolvere questo in modo che si ottiene il SINGLE_TOP comportamento che si vuole, l'obiettivo generale che è il riutilizzo di un'attività esistente, invece di crearne uno nuovo...

Primo modo (come descritto nella sezione di commento del accettati risposta):Si potrebbe aggiungere un launchMode di "singleTask" per la vostra Attività.Questo costringerebbe onNewIntent() perché singleTask significa che ci può essere solo una istanza di una particolare attività in un dato compito.Questo è un po ' sporca soluzione, però, perché se la vostra applicazione ha bisogno di più istanze di tale attività in una situazione particolare (come faccio io per il mio progetto), sei fregato.

Secondo modo (migliore): Invece di FLAG_ACTIVITY_SINGLE_TOP, utilizzare FLAG_ACTIVITY_REORDER_TO_FRONT.Questo è in grado di riutilizzare l'attività esistente istanza spostandolo verso la cima dello stack (onNewIntent() sarà chiamato come previsto).

Lo scopo principale di FLAG_ACTIVITY_SINGLE_TOP è quello di impedire la creazione di più istanze di un'Attività.Per esempio, quando tale attività può essere avviata tramite un intento che viene da fuori, di applicazione principale di attività.Per la commutazione interna tra le attività che nella mia applicazione, ho scoperto che FLAG_ACTIVITY_REORDER_TO_FRONT è generalmente quello che voglio, invece.

Imposta questo flag per il vostro intento:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top