Android: Wyczyść tylny stos

330

W Androidzie mam pewne działania, powiedzmy A, B, C.

W A używam tego kodu, aby otworzyć B:

Intent intent = new Intent(this, B.class);
startActivity(intent);

W B używam tego kodu, aby otworzyć C:

Intent intent = new Intent(this, C.class);
startActivity(intent);

Gdy użytkownik stuknie przycisk w C, chcę wrócić do A i wyczyścić tylny stos (zamknąć zarówno B, jak i C). Więc kiedy użytkownik użyje przycisku Wstecz B i C się nie pokaże, próbowałem:

Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

Ale B i C nadal się wyświetlają, jeśli użyję przycisku Wstecz, gdy wrócę do aktywności A. Jak mogę tego uniknąć?

Jaskółka oknówka
źródło

Odpowiedzi:

438

Spróbuj dodać FLAG_ACTIVITY_NEW_TASKzgodnie z opisem w dokumentacji dla FLAG_ACTIVITY_CLEAR_TOP:

Ten tryb uruchamiania może być również stosowany z dobrym skutkiem w połączeniu z FLAG_ACTIVITY_NEW_TASK: jeśli zostanie użyty do uruchomienia aktywności root zadania, spowoduje przeniesienie aktualnie uruchomionej instancji tego zadania na pierwszy plan, a następnie wyczyści go do stanu root. Jest to szczególnie przydatne na przykład podczas uruchamiania działania z poziomu menedżera powiadomień.

Twój kod do uruchomienia Ato:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
CurrentActivity.this.finish(); // if the activity running has it's own context


// view.getContext().finish() for fragments etc.
Jake Basile
źródło
28
Dzięki, ale próbowałem tego. Mimo to po dotknięciu przycisku Wstecz po ponownym wyświetleniu litery C. Czego mi brakuje?
Martin
4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
dzeikei,
8
nie działa dla mnie jednak wywoływanie funkcji kończenia () na czynności źródłowej robi to, co musiałem osiągnąć
2cupsOfTech
10
Miałem ten sam problem, że to nie działało. Tym, co naprawiło to dla mnie, było wywołanie wykończenia () po rozpoczęciu nowej działalności
Arno
20
Dodałem też jeszcze jeden wyraźny zamiar = nowy zamiar (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (cel); koniec();
Sam
147
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
diesel
źródło
8
Z całym szacunkiem dla CLEAR_TOPflagi - ta kombinacja jest TYLKO tą, która całkowicie wyczyściła cały stos i uczyniła nową aktywność jedyną w aplikacji. Dziękuję Ci!
Aviel Gross
8
Jaka jest różnica między tą a zaakceptowaną odpowiedzią?
Yuri Heupa,
7
Dzięki, różnica w stosunku do przyjętej odpowiedzi polega na tym, że przy tej fladze nie musimy wywoływać activity.finish
Pablo Cegarra
1
FLAG_ACTIVITY_CLEAR_TASK doskonale współpracował z NEW_TASK
Shamsul Arefin Sajib
1
To powinna być zaakceptowana odpowiedź. Dziękuję Ci bardzo.
MD Duński Ansari
77

Co z dodawaniem pliku manifestu dla powiązanej aktywności:

android:noHistory="true"

do definicji aktywności B i C? Nie zostaną dodane do backstacka. Nie jestem pewien, czy tego właśnie chcesz.

Dominik Helleberg
źródło
3
Bądź bardzo ostrożny podczas korzystania z tego - Jeśli używasz logowania za pomocą FB lub jakiejkolwiek podobnej funkcji
Skynet
2
@ Skynet Dlaczego? Jakie są problemy z tym związane?
Alfie Woodland,
8
Po przekazaniu kontroli FB na logowanie ze strony bez historii, aplikacja FB nie teraz ląduje po zalogowaniu użytkownika, w moim przypadku wracała do ekranu głównego telefonu i prawie straciłam pracę!
Skynet,
To nie pozwala aktywności dodanej do backstacka ... to nie jest poprawne rozwiązanie.
Tarun
Dokładnie szukam
Masum
63

Długo mi to przeszkadza. W końcu to wypracowałem:

Fragmentem użyj:

Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

W Aktywności użyj (dodaj jeszcze jedną flagę zamiaru w Intent.FLAG_ACTIVITY_CLEAR_TASKporównaniu do fragmentu):

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Geng Jiawen
źródło
1
Jeśli używasz androidanotacji, musisz dodać: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade
Aktywność solutioin działała dla mnie dobrze. Chociaż myślę, że z API 16 rozwiązanie Daniela Schulera jest łatwiejsze.
PhilippS,
Dziękuję Yosafatade, tego mi brakowało!
Marty Miller,
30
  1. Dodaj android:launchMode="singleTop"do elementu aktywności w manifeście dla działania A
  2. Następnie użyj intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) i intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)podczas rozpoczynania działania A

Oznacza to, że po uruchomieniu działania A wszystkie zadania nad nim są usuwane, dzięki czemu A jest na górze. Nowy tylny stos jest tworzony z A w katalogu głównym, a użycie singleTopzapewnia, że ​​uruchomisz A tylko raz (ponieważ A jest teraz na wierzchu z powodu ..._CLEAR_TOP).

Joseph Earl
źródło
3
Tak. tego właśnie używam, ale to nie robi tego. Nadal pojawia się C, gdy nacisnę przycisk Wstecz.
Martin
Dziwne, użyłem tego w projekcie i działa dobrze ... naciśnięcie wstecz przenosi mnie do ekranu głównego. Być może dzieje się coś jeszcze. Czy możesz opublikować swój manifest?
Joseph Earl
Uruchomiłem ponownie emulator i teraz działa on tak, jak powiedziałeś. Bardzo dziękuję za Twoją pomoc!
Martin
singleTop nie powinien mieć nic wspólnego z czyszczeniem stosu.
stdout
29

Począwszy od API 16 (Jelly Bean), możesz po prostu zadzwonić finishAffinity().

Teraz możesz także dzwonić ActivityCompat.finishAffinity(Activity activity)za pomocą biblioteki kompatybilności.

Pamiętaj, aby ustawić taskAffinity w manifeście na nazwę pakietu unikalną dla tej grupy działań.

Zobacz więcej informacji:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29

Daniel Schuler
źródło
Naprawdę przydatne i łatwe rozwiązanie, jeśli jesteś już na API 16. Pracował dla mnie!
Filipiny,
3
przypomnienie: zadziała to tylko dla działań w tym samym zadaniu Nazwa świętości
Ryan
działa to tylko wtedy, gdy masz tylko jedno działanie w historii.
przyjechał
17

Spróbuj użyć

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

i nie

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Muhammad Aamir Ali
źródło
11

Jeśli twoja aplikacja ma minimalną wersję SDK 16, możesz użyć finishAffinity ()

Zakończ to działanie, a także wszystkie działania bezpośrednio pod nim w bieżącym zadaniu, które mają to samo powinowactwo.

Dla mnie to działa. Na ekranie Top Payment usuń wszystkie aktywacje back-stack,

 @Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29

Jaydeep purohit
źródło
9

Zgodnie z Wakka w Usuwanie aktywności ze stosu historii ...


Dodaj android:noHistory="true"atrybut do swojego <activity>w AndroidManifest.xmlnastępujący sposób:

    <activity android:name=".MyActivity"
        android:noHistory="true">
    </activity>
Richard Le Mesurier
źródło
8

Do przyszłych badań wypróbuj ten kod.

Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
GeetT
źródło
Te flagi w końcu dla mnie zadziałały. To, co zrobiłem, to to, że zacząłem tę samą Aktywność, w której byłem przy tych flagach i boolowskie dodatkowe WYJŚCIE = prawda. W funkcji onCreate () sprawdziłem parametry uruchamiania dla EXIT i nazwałem wykończenie (), jeśli było ustawione na true. To bardzo kłopotliwe, aby zamknąć własną aplikację.
Janne Oksanen,
8

Użyj finishAffinity (); w zadaniu C podczas uruchamiania zadania A w celu wyczyszczenia działań backstack.

baswaraj
źródło
tylko ta odpowiedź działa dla mnie. Intent.FLAG_ACTIVITY_CLEAR_TOP i Intent.FLAG_ACTIVITY_NEW_TASK nie są wymagane
nuttynibbles
7

Użyj tego kodu, aby rozpocząć nowe działanie i zamknąć lub zniszczyć wszystkie inne stosy działań lub stosy wsteczne.

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Pankaj Talaviya
źródło
5
Use finishAffinity() to clear all backstack with existing one.

Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 

    - Activity B will be finished / removing from stack.
    - Activity A will be finished / removing from stack.
    - Activity C will finished / removing from stack.
Firzan Shaikh
źródło
5

Znalazłem interesujące rozwiązanie, które może pomóc. Zrobiłem to w mojej onBackPressed()metodzie.

finishAffinity();
finish();

FinishAffinityusuwa połączenie istniejącej aktywności ze stosem. A potem wykończenie pomaga wyjść z tej aktywności. Które ostatecznie zamkną aplikację.

Sujith Royal
źródło
4

Znalazłem tutaj odpowiedzi trochę mylące, ponieważ kod w pierwotnym pytaniu wydaje się działać dobrze dla mnie?

Ponieważ A jest działaniem głównym, rozpoczęcie od B lub C tylko z FLAG_ACTIVITY_CLEAR_TOP usuwa B i C z tylnego stosu.

ianjoyner
źródło
4

W kotlin jest prawie tak samo jak java. Tylko | symbol jest zastąpiony przez lub tekst. Więc jest napisane jak

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
Exigente05
źródło
3

Wypróbowałem wszystkie rozwiązania i żadne nie działało indywidualnie dla mnie. Moje rozwiązanie to:

Zadeklaruj Activity Ajako SingleTopza pomocą [android:launchMode="singleTop"]manifestu systemu Android.

Teraz dodaj następujące flagi podczas uruchamiania Az dowolnego miejsca. Wyczyści stos.

Intent in = new Intent(mContext, A.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(in);
finish();
Tarun
źródło
2

Intent.FLAG_ACTIVITY_CLEAR_TOPnie będzie działać w tym przypadku. Proszę użyć(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Aby uzyskać więcej informacji, zapoznaj się z dokumentacją.

Ashish Saini
źródło
2

Wydaje mi się, że musisz zacząć Activity Cod Activity Bużycia startActivityForResult(). Po kliknięciu w przycisk Activity C, rozmowy setResult(RESULT_OK)i finish()tak Activity Csię skończyło. Wewnątrz Activity Bmożesz uzyskać onActivityResult()odpowiedź, wzywając finish()się, a następnie zostaniesz zabrany z powrotem do Activity A.

Maximus
źródło
7
Tak, ale jeśli między A i C są 42 zajęcia, będzie to raczej nużące. Flaga FLAG_ACTIVITY_CLEAR_TOP ma robić bezpośrednio to, czego chce OP.
Guillaume Brunerie
Byłby to mniej niż optymalny sposób na osiągnięcie tego, czego chce OP, i jak powiedział @ Guillaume, wymagałby kodu we wszystkich działaniach między rootem a górną częścią stosu.
Jake Basile,
Zanotowano. Są to flagi, o których najwyraźniej muszę się dowiedzieć.
Maximus
1

logout.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);

Abhijeet
źródło
1

Można użyć tego przykładu, aby połączyć się Activity AzActivity C

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);

Vipin Yadav
źródło
1

dla mnie dodanie Intent.FLAG_ACTIVITY_CLEAR_TASKrozwiązało problem

Intent i = new Intent(SettingsActivity.this, StartPage.class);
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
finish();
Mohamed Mo'nes
źródło
1

Zaawansowany, wielokrotnego użytku Kotlin:

Możesz ustawić flagę bezpośrednio za pomocą metody setter. W Kotlin orjest zamiennikiem Java bitowej lub |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Jeśli użyjesz tego więcej niż raz, utwórz funkcję rozszerzenia Intent

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Następnie możesz bezpośrednio wywołać tę funkcję przed rozpoczęciem zamiaru

intent.clearStack()

Jeśli potrzebujesz opcji dodania dodatkowych flag w innych sytuacjach, dodaj opcjonalny parametr do funkcji rozszerzenia.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
Gibolt
źródło
0

Oprócz tego FLAG_ACTIVITY_CLEAR_TOPmożesz spróbować dodać Intent.FLAG_ACTIVITY_SINGLE_TOP:

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

James
źródło
Wpłynęłoby to tylko na aktywność na górze stosu, a nie na jego rdzeń.
Jake Basile,
0

Podany kod działa poprawnie. Próbowałem w przykładzie cyklu życia aplikacji.

Nie mam B i C na ostatnim stosie po rozpoczęciu aktywności A z flagą, FLAG_ACTIVITY_CLEAR_TOP

Sathesh
źródło
0

zadzwoniłem activity_name.this.finish()po rozpoczęciu nowego zamiaru i zadziałało to dla mnie.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Ale to nie zadziała dla mnie ... Nie sugeruję użycia tego rozwiązania, ale jeśli ustawienie flagi nie zadziała, możesz spróbować. Ale nadal polecam, nie używaj go

Zamień-IOS-Android
źródło
0

Dodaj w zamian BEZ flagi historii.

W ćwiczeniu B rozpocznij działanie C jak poniżej >>>>>>

Intent intent = new Intent(this, C.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
startActivity(intent);
finish();
Arun Sharma
źródło
0

W manifestie

android:launchMode="singleTask"

i

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
maczuga
źródło
0

Dodaj to do swojego Activity BiActivity C

android:noHistory="true"

lub Override onBackPressedfunkcję, aby uniknąć naciśnięcia wstecz za pomocą return.

@Override
public void onBackPressed() {
   return;
}
Renjith JR
źródło
0

Skorzystaj z metody setFlags (), aby wyczyścić tylną stronę otwartą wszystkie działania zamknij i uruchom swoją aktywność

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Pankaj Talaviya
źródło