Zakończ wszystkie poprzednie działania


368

Moja aplikacja ma następujące ekrany przepływu:

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Teraz mam wspólny log out przycisk na każdym ekranie

( Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

Chcę, aby po kliknięciu przycisku wylogowania (z dowolnego ekranu) wszystkie ekrany zostały zakończone i Log inotworzył się nowy ekran .

Próbowałem prawie wszystkich, FLAG_ACTIVITYaby to osiągnąć. Przeglądam także niektóre odpowiedzi w przepełnieniu stosu, ale nie jestem w stanie rozwiązać problemu. Moja aplikacja działa na Androidzie 1.6, więc nie mogę jej używaćFLAG_ACTIVITY_CLEAR_TASK

Czy jest jakiś sposób na rozwiązanie tego problemu?


Czy prowadzisz zagnieżdżone działania za pomocą startActivityForResult?
— woodshy 13.06.11

nie. Wszystkie działania rozpoczynają się od startActivity.
— Tanmay Mandal

Korzystam z zagnieżdżonych działań, podczas gdy dorsz uruchamia metodę finishaffinitytask () w zagnieżdżonych działaniach. czy to zmienia zachowanie? ponieważ czasami otrzymuję komunikat o niepowodzeniu dostarczania wyniku ResultInfo, gdy uruchomione jest poleceniekończenie zadania.
— Ripal Tamboli

Sprawdź tę odpowiedź, to z pewnością pomoże ci stackoverflow.com/a/25159180/2732632
— Kimmi Dhingra

3
Android 21 wprowadził Activity.finishAndRemoveTask ().
— Joseph Johnson

Odpowiedzi:


543

Posługiwać się:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Spowoduje to wyczyszczenie wszystkich działań w domu.

Zakładając, że kończysz ekran logowania, gdy użytkownik loguje się i tworzona jest strona główna, a następnie wszystkie ekrany od 1 do 5 na górze tego. Kod, który opublikowałem, spowoduje powrót do ekranu głównego po zakończeniu wszystkich innych działań. Możesz dodać dodatkowy cel i przeczytać to w aktywności na ekranie głównym i zakończyć również (może ponownie uruchomić ekran logowania z tego miejsca lub coś takiego).

Nie jestem pewien, ale możesz także spróbować zalogować się przy użyciu tej flagi. W tym przypadku nie wiem, jak zostaną uporządkowane działania. Więc nie wiem, czy to wyczyści te pod ekranem, na którym jesteś, w tym ten, na którym aktualnie jesteś, ale zdecydowanie jest to dobra droga.

Mam nadzieję że to pomoże.


Użytkownik pokazuje swój pierwszy ekran jako ekran główny, to jest główny problem.
— Tanmay Mandal

Cóż, mam swoją odpowiedź, musisz wrócić do ekranu głównego i dokończyć ten. więc proces wywołuje powyższe zamiary z dowolnego ekranu. otrzymaj zamiar na ekranie głównym i od razu pomyśl o logowaniu i ukończ dom po metodzie startActivity. możesz także przesłonić oczekującą animację, ustawiając na zero dla wejść i wyjść, aby nie pokazywała przejścia (robię to, ponieważ wydaje się to trochę szybsze). więc to powinno działać dobrze dla tego, czego potrzebujesz.
— DArkO

10
Zamiast zadeklarować działanie jako singleInstance, rozważ użycie FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOPjako flagi dla zamiaru. To zakończy działania interwencyjne i rozpocznie (lub przywróci na pierwszy plan) pożądane działanie.
— CommonsWare

13
@ CommonsWare Dodanie intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);do mojej aktywności nie pomogło mi. Nie zakończyło interwencji. Po ponownym naciśnięciu ekranu logowania widzę poprzednie działania. Oto mój kod Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
— Tanmay Mandal,

26
ten kod usuwa tylko górny stos działań, aby wyczyścić wszystkie działania intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
— Ajay Venugopal

318

Możesz spróbować Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Całkowicie wyczyści wszystkie poprzednie działania i rozpocznie nowe działanie.


11
Właściwe rozwiązanie, ale tylko API 11+
— riwnodennyk

Skończyło się na użyciu tej dodatkowej flagi, ponieważ nie powoduje to opóźnienia przy wyświetlaniu głównej aktywności (nie zrestartuje jej, więc jest znacznie szybsza).
— Maurizio

2
@riwnodennyk dlaczego API 11+?
— Muhammad Babar

17
Użyj IntentCompat.FLAG_ACTIVITY_CLEAR_TASK dla wersji wcześniejszych 11
— Steven Pena

2
@ono Tak. To powinno być wszystko, czego potrzebujesz. Upewnij się, że tryb uruchamiania działania docelowego jest ustawiony w manifeście jako „singleTask”.
— Steven Pena,

137

Przed uruchomieniem nowego działania wystarczy dodać następujący kod:

finishAffinity();

Lub jeśli chcesz, aby działał w poprzednich wersjach Androida:

ActivityCompat.finishAffinity(this);

12
ActivityCompat.finishAffinity (this); wywołuje activity.finish () dla api <16. Więc to nie zadziała.
— Aamir Abro,

1
@Beto Caldas, sam potwierdziłem kod źródłowy, nie będzie działać dla API <16, jak wspomniał AamirAbro. To po prostu zakończy działanie, które przekazujesz API <16.
— HendraWD

39

Gdy użytkownik chce wyjść ze wszystkich otwartych działań , powinien nacisnąć przycisk, który ładuje pierwsze działanie, które jest uruchamiane po uruchomieniu aplikacji, wyczyścić wszystkie pozostałe działania, a następnie zakończyć ostatnie działanie. Uruchom następujący kod, gdy użytkownik naciśnie przycisk wyjścia. W moim przypadku LoginActivityjest to pierwsze działanie w moim programie do uruchomienia.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

Powyższy kod usuwa wszystkie działania oprócz LoginActivity. Następnie wstaw następujący kod do LoginActivity's' onCreate(...), aby nasłuchiwać, kiedy LoginActivityzostanie odtworzony i przekazany został sygnał „EXIT”:

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Dlaczego tak trudny jest przycisk wyjścia w Androidzie?

System Android stara się zniechęcić użytkownika do posiadania przycisku „wyjdź” w aplikacji, ponieważ chce, aby użytkownik nigdy nie dbał o to, czy używane przez niego programy działają w tle, czy nie.

Programiści systemu operacyjnego Android chcą, aby Twój program mógł przetrwać nieoczekiwane zamknięcie i wyłączenie telefonu, a gdy użytkownik uruchomi ponownie program, rozpocznie pracę od miejsca, w którym zakończył. Dzięki temu użytkownik może odbierać połączenia telefoniczne podczas korzystania z aplikacji i otwierać mapy, które wymagają zwolnienia aplikacji w celu uzyskania większej ilości zasobów.

Gdy użytkownik wznawia twoją aplikację, odbiera ją tam, gdzie ją przerwał, bez żadnych zakłóceń. Ten przycisk wyjścia przejmuje władzę od menedżera aktywności, potencjalnie powodując problemy z automatycznie zarządzanym cyklem życia programu Android.


31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Działa to dla wszystkich wersji Androida. Gdzie IntentCompatklasa dodana w bibliotece wsparcia Android.


IntentCompat.FLAG_ACTIVITY_CLEAR_TASKnie jest rozpoznawany, użyj Intentzamiast IntentCompat.
— CoolMind,

30

Użyj następujących działań

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

usuń flagę CLEAR_TASK w celu użycia fragmentu.

Mam nadzieję, że może to być przydatne dla niektórych osób.


24

Chyba się spóźniłem, ale odpowiedź jest prosta i krótka. W działaniu znajduje się metoda finishAffinity (), która zakończy bieżącą aktywność i wszystkie działania nadrzędne, ale działa tylko w systemie Android 4.1 lub nowszym.

W przypadku API 16+ użyj

finishAffinity();

Dla osób poniżej 16, użyj

ActivityCompat.finishAffinity(YourActivity.this);

Mam nadzieję, że to pomoże!


21

Od developer.android.com :

public void finishAffinity ()

Dodano w API 16 poziom

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. Jest to zwykle używane, gdy aplikacja może zostać uruchomiona do innego zadania (na przykład z ACTION_VIEW typu treści, który rozumie), a użytkownik skorzystał z nawigacji w górę, aby przełączyć się z bieżącego zadania do własnego. W takim przypadku, jeśli użytkownik przejdzie w dół do innych działań drugiej aplikacji, wszystkie z nich powinny zostać usunięte z pierwotnego zadania jako część przełącznika zadań.

Pamiętaj, że to wykończenie nie pozwala na dostarczenie wyników do poprzedniej aktywności, a wyjątek zostanie zgłoszony, jeśli spróbujesz to zrobić.


19

Na marginesie, dobrze wiedzieć
Ta odpowiedź działa ( https://stackoverflow.com/a/13468685/7034327 )

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();

podczas gdy to nie działa

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() zastępuje wszystkie poprzednie flagi i nie dodaje żadnych nowych flag, gdy to .addFlags()robi.

To też zadziała

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Świetne wyjaśnienie różnicy między setFlag a addFlag, dziękuję
— Pelanes

13

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


10

Rozwiązanie, które wdrożyłem w tym celu (myślę, że znalazłem je gdzieś na Stack Overflow, ale nie pamiętam, więc dzięki temu, kto to zrobił):

Z dowolnego ze swoich działań wykonaj to:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Następnie w swojej LoginActivity, nadpisz onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3
To zazwyczaj bardzo zły pomysł, ponieważ może działać, wprowadza punkt kontaktowy, który może się złamać w przyszłości i trudno będzie go debugować. Mówię ci z doświadczenia :)
— Martin Marconcini

10

W przypadku przycisku wylogowania na ostatnim ekranie aplikacji użyj tego kodu w detektorze przycisku wylogowania, aby zakończyć wszystkie otwarte poprzednie działania, a problem zostanie rozwiązany.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}

8
    Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

6
dlaczego FLAG_ACTIVITY_CLEAR_TASK dwa razy?
— Choletski

1
Z tego, co rozumiem, .setFlags zastępuje poprzednie flagi i nie dołącza żadnych flag. .addFlags jest tym, czego chciałeś użyć, jak sądzę? Przyczyna całego kodu powyżej i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); zostaje
— usunięty

addFlags Działa dla mnie
— Jamil,

1
setFlagszastąpi wszystkie poprzednie, więc ostatnie setFlagsjest tylko ważne, poprzednie są zastąpione. Więc nie musisz dzwonići1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
— mtrakal

8

Mam ten sam problem, z którego możesz skorzystać IntentCompat, taki jak ten:

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

ten kod działa dla mnie.

Interfejs API Androida 17


8

W moim przypadku używam finishAffinity()funkcji w ostatniej aktywności, takiej jak:

finishAffinity()
startHomeActivity()

Mam nadzieję, że się przyda.



6

Zaloguj się> Strona główna-> ekran 1-> ekran 2-> ekran 3-> ekran 4-> ekran 5

na ekranie 4 (lub dowolnym innym) ->

StartActivity (Zaloguj się)
z
FLAG_ACTIVITY_CLEAR_TOP


2
Po naciśnięciu przycisku Wstecz wszystkie poprzednie działania są wyświetlane w kolejności, w jakiej były. Działania te należy zamknąć, gdy kliknięty zostanie przycisk wylogowania, na stosie będzie tylko jedno działanie i będzie to działanie związane z logowaniem. ekran logowania. Użytkownik uruchamia się z ekranu głównego.
— Tanmay Mandal

6

dla API> = 15 do API 23 proste rozwiązanie.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

Opracuj swoją odpowiedź, aby każdy mógł z niej skorzystać.
— Shubhamoy,

5

Jeśli korzystasz startActivityForResult()z poprzednich działań, po prostu zastąp OnActivityResult()i wywołaj finish();metodę znajdującą się w nim we wszystkich działaniach. Spowoduje to wykonanie zadania ...


Nie, używam startActivitytylko.
— Tanmay Mandal

Trudno będzie utrzymać onActivityResultkażdą aktywność. Wdrożyłem sugestię DArkO i osiągnąłem swój cel i dziękuję za pomoc.
— Tanmay Mandal

3

Gdy użytkownik kliknie przycisk wylogowania, a następnie napisze następujący kod:

Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

A także, gdy po zalogowaniu, jeśli wywołasz nową aktywność, nie używaj kończenia ();


2

Po prostu, kiedy przejdziesz z ekranu logowania, a nie po zakończeniu ekranu logowania.

Następnie we wszystkich działaniach do przodu użyj tego do wylogowania:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

Działa idealnie.


1

Jeśli zalogujesz użytkownika, screen 1a następnie przejdziesz do innych ekranów, użyj

Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Po naciśnięciu przycisku Wstecz wszystkie poprzednie działania są wyświetlane w kolejności, w jakiej były. Działania te należy zamknąć, gdy kliknięty zostanie przycisk wylogowania, na stosie będzie tylko jedno działanie i będzie to działanie związane z logowaniem.
— Tanmay Mandal

Jeśli chcesz tego zachowania, musisz zastąpić onKeyDowni onBackPressed(lub onKeyDown, jeśli chcesz obsługiwać wersje Androida <2.0) w każdym ze swoich działań (oprócz logowania) i startActivity(login)tam, jak pokazano powyżej.
— Gabriel Negut,

Mam przycisk, który przeniesie mnie do ekranu logowania kończącego wszystkie działania na stosie. Czy to możliwe?
— Tanmay Mandal

1

Znalazłem w ten sposób, wyczyści całą historię i wyjdzie

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);

1

Chyba się spóźniłem, ale odpowiedź jest prosta i krótka. W działaniu znajduje się metoda finishAffinity (), która zakończy bieżącą aktywność i wszystkie działania nadrzędne, ale działa tylko w systemie Android 4.1 lub nowszym.

W przypadku API 16+ użyj

finishAffinity ();

Dla osób poniżej 16, użyj

ActivityCompat.finishAffinity (YourActivity.this);

Mam nadzieję, że to pomoże!

shareedit odpowiedział 27 maja 18 o 8:03

Akshay Taru


0

Uważam, że to rozwiązanie działa na każdym urządzeniu pomimo poziomu interfejsu API (nawet <11)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

0

Najlepszy sposób na zamknięcie wszystkich poprzednich działań i wyczyszczenie pamięci

finishAffinity()
System.exit(0);

0
startActivity(
                Intent(this, LoginActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
            )
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.