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ąć?

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.

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);

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.


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);

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).


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


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);

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



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();

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.


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);

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.

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ę.


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.


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)

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();

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ą.


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.


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);


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);


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();

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
}

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);


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


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


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();

0

W manifestie

android:launchMode="singleTask"

i

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

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;
}

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);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.