Cancellare l'intero stack storia e iniziare una nuova attività su Android
-
28-09-2019 - |
Domanda
E 'possibile avviare un'attività in pila, cancellare tutta la storia prima di esso?
La situazione
Ho una pila un'attività che o va A-> B-> C o B-> C (schermo A seleziona gli utenti gettone, ma molti utenti hanno solo un singolo token).
Nella schermata C l'utente possono intraprendere un'azione che rende schermo B valido, quindi l'applicazione vuole portarli a schermo A, indipendentemente dal fatto che è già in pila. Schermo A dovrebbe quindi essere l'unico punto all'ordine del pila nella mia applicazione.
Note
Ci sono molte altre domande simili, ma non ho trovato nulla che risponde a questa domanda esatta. Ho provato a chiamare getParent().finish()
- questo si traduce sempre in un'eccezione di puntatore nullo. FLAG_ACTIVITY_CLEAR_TOP
funziona solo se l'attività è già in pila.
Soluzione
Nel livello di API 11 una nuova bandiera Intent è stato aggiunto proprio per questo: Intent.FLAG_ACTIVITY_CLEAR_TASK
Giusto per chiarire, usare questo:
Java
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Kotlin
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
Purtroppo per API lvl <= 10, non ho ancora trovato una soluzione pulita per questo. I "DontHackAndroidLikeThis" soluzione è davvero pura aggiustamenti. Non dovresti farlo. :)
Modifica
Come da commento @ Ben Pearson s ', per l'API <= 10 ora si può usare IntentCompat classe per lo stesso. Si può usare la bandiera IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
al compito chiaro. Così si può sostenere il livello pre API 11 pure.
Altri suggerimenti
Caso 1: Solo due attività di A e B:
Qui il flusso di attività è A-> B .On clic BackButton da B abbiamo bisogno di chiudere l'applicazione poi mentre a partire Activity B da A solo finitura call () questo impedirà Android di memorizzazione Attività A alla Backstack.eg per attività di A è Caricamento in corso / schermata iniziale di applicazione.
Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();
Caso 2: Più di due activitiy:
Se c'è un flusso come A-> B-> C-> D> B e facendo clic sul pulsante indietro nel Activity B venendo da attività D.In quel caso dovremmo usare.
Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
qui Attività B verrà avviato dal backstack, piuttosto che una nuova istanza a causa di Intent.FLAG_ACTIVITY_CLEAR_TOP e Intent.FLAG_ACTIVITY_NEW_TASK cancella lo stack e la rende la parte superiore one.So quando premiamo il pulsante di nuovo l'intera applicazione verrà terminata.
Con Android più recente versione> = 16 API uso finishAffinity()
approccio è adatto per> = 16 API.
Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
- Il suo è stessa partendo nuova attività, e cancellare tutti stack.
- O Riavvia per MainActivity / FirstActivity.
ho trascorso un paio d'ore anche su questo ... e sono d'accordo che i suoni FLAG_ACTIVITY_CLEAR_TOP come quello che ci si vuole: cancellare l'intero stack, fatta eccezione per l'attività in fase di lancio, in modo che il pulsante Indietro chiude l'applicazione. Eppure, come detto Mike Repass, FLAG_ACTIVITY_CLEAR_TOP funziona solo quando l'attività che stai lanciando è già in pila; quando l'attività non c'è, la bandiera non fa nulla.
Che fare? Mettere l'attività dell'essere lancio nello stack con FLAG_ACTIVITY_NEW_TASK, che rende l'attività che l'inizio di una nuova attività sullo stack storia. Quindi aggiungere il flag FLAG_ACTIVITY_CLEAR_TOP.
Ora, quando FLAG_ACTIVITY_CLEAR_TOP va a trovare la nuova attività nello stack, sarà lì e si fermò prima di tutto viene cancellato.
Ecco la mia funzione di logout; il parametro View è il tasto a cui della funzione allegata.
public void onLogoutClick(final View view) {
Intent i = new Intent(this, Splash.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
finish();
}
Non si dovrebbe cambiare la pila. pulsante indietro Android dovrebbe funzionare come in un browser web.
mi viene in mente un modo per farlo, ma è piuttosto un hack.
-
Fai la tua attività
singleTask
aggiungendolo alAndroidManifest
Esempio:<activity android:name=".activities.A" android:label="@string/A_title" android:launchMode="singleTask"/> <activity android:name=".activities.B" android:label="@string/B_title" android:launchMode="singleTask"/>
-
Estendere
Application
che terrà la logica di dove andare.
Esempio:
public class DontHackAndroidLikeThis extends Application {
private Stack<Activity> classes = new Stack<Activity>();
public Activity getBackActivity() {
return classes.pop();
}
public void addBackActivity(Activity activity) {
classes.push(activity);
}
}
Da A a B:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class);
startActivity(this, B.class);
Da B a C:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class);
startActivity(this, C.class);
In C:
If ( shouldNotGoBackToB() ) {
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.pop();
}
e gestire il pulsante Indietro per pop()
dallo stack.
Ancora una volta, non si dovrebbe fare questo:)
Subito dopo aver avviato una nuova attività, utilizzando startActivity
, assicuratevi di chiamare finish()
in modo che l'attività in corso non è accatastato dietro quella nuova.
Prova questo:
Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
Prova sottostante Codice,
Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
Intent.FLAG_ACTIVITY_CLEAR_TASK|
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Per me non dei metodi di cui sopra non funziona.
Basta fare questo per cancellare tutte le attività precedenti :
finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)
ho trovato troppo semplice mod solo fare questo nuovo elemento aggiuntivo in AndroidManifest
come: -
<activity android:name=".activityName"
android:label="@string/app_name"
android:noHistory="true"/>
il android:noHistory
cancellerà la tua attività indesiderate da Pila.
A volte il vostro emulatore di forza di Android non riesce a strumento di connessione eclissi DDMS e chiedere ADB per l'avvio manuale. In questo caso è possibile avviare o interrompere l'adb utilizzando il prompt dei comandi.