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