Jak używasz Intent.FLAG_ACTIVITY_CLEAR_TOP do czyszczenia stosu aktywności?


85

Przeczytałem kilka postów na temat korzystania z tego, ale chyba czegoś brakuje, ponieważ nie działa dla mnie. Moje działanie A ma launchmode = "singleTop" w manifeście. Rozpoczyna czynność B z launchmode = "singleInstance". Działanie B otwiera przeglądarkę i odbiera i zwraca z powrotem, dlatego jest to singleInstance. Próbuję zastąpić przycisk Wstecz, aby użytkownik został odesłany z powrotem do działania A, a następnie mógł nacisnąć przycisk Wstecz, aby opuścić działanie, zamiast wracać do działania B.

// activity B
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
  && keyCode == KeyEvent.KEYCODE_BACK
  && event.getRepeatCount() == 0) onBackPressed();
 return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
 startActivity(new Intent(this, UI.class)
 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
 return;
}

Po powrocie z przeglądarki stos to ... A, B, Browser, B

Oczekuję, że ten kod zmieni stos na ... A ... tak, że ponowne naciśnięcie przeniesie użytkownika z powrotem do ekranu głównego.

Zamiast tego wydaje się, że zmienia stos na ... A, B, Browser, B, A ... tak, jakby tych flag nie było.

Próbowałem wywołać finish () w działaniu B po startActivity, ale potem przycisk Wstecz przenosi mnie z powrotem do przeglądarki!

czego mi brakuje? Dziękuję Ci!

Odpowiedzi:


72

@bitestar ma poprawne rozwiązanie, ale jest jeszcze jeden krok:

Został on ukryty w docs, jednak trzeba zmienić launchModez Activityinną niż standard. W przeciwnym razie zostanie zniszczony i odtworzony zamiast resetowania do góry.


52
Właściwie ... Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPwystarczy.
Derk-Jan,

Sprawdź przykład rozwiązania Steel_fedex.
Darpan,

2
więc gdzie do diabła jest rozwiązanie Steel_fedex ?!
ChangWon Jeong Juicycool

112

Rozpocząłem Ćwiczenie A-> B-> C-> D. Kiedy przycisk Wstecz zostanie naciśnięty w działaniu D, chcę przejść do działania A. Ponieważ A jest moim punktem początkowym, a zatem już na stosie, wszystkie działania na górze A są wyczyszczone i nie można wrócić do żadnego innego działania z A .

To faktycznie działa w moim kodzie:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent a = new Intent(this,A.class);
        a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(a);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}       

4
To rozwiązanie zamyka wszystkie działania pośredniczące; ale także ponowne uruchomienie RootActivity. Możesz sprawdzić rozwiązanie @ Steel_Fedex poniżej. Robi to samo, ale nie uruchamia ponownie RootActivity.
Darpan,

To najlepsze rozwiązanie w moim przypadku. Właściwie chcę, aby aktywność roota ponownie się uruchomiła
Tash Pemhiwa,

24

W tym celu używam FLAG_ACTIVITY_CLEAR_TOPflagi do uruchamiania Intent
(bez FLAG_ACTIVITY_NEW_TASK)

i jako launchMode = "singleTask"manifest do rozpoczętej działalności.

Wygląda na to, że działa tak, jak potrzebuję - aktywność nie uruchamia się ponownie, a wszystkie inne są zamknięte.


Sprawdziłem, rozwiązanie Bitster nie działa. Chociaż to rozwiązanie zadziałało. RootActivity nie uruchomiło się ponownie.
Darpan

Mądrzej dobieraj słowa. Rozwiązanie Bitestar faktycznie działa!
Jesper Bischoff-Jensen

singleTask działa dla mnie, więc Activity nie będzie odtwarzać i obsługiwać zdarzenia w onNewIntent.
Jishi Chen

11

Chociaż to pytanie ma już wystarczające odpowiedzi, pomyślałem, że ktoś chciałby wiedzieć, dlaczego ta flaga działa w tak dziwny sposób, oto, co znalazłem w dokumentacji Androida

Aktualnie działające wystąpienie działania B w powyższym przykładzie otrzyma nową intencję, którą zaczynasz tutaj, w swojej metodzie onNewIntent () lub zostanie zakończone i uruchomione ponownie z nową intencją.

Jeśli zadeklarował tryb uruchamiania jako „wiele” (domyślny) i nie ustawiłeś FLAG_ACTIVITY_SINGLE_TOP w tym samym celu, zostanie zakończony i ponownie utworzony; dla wszystkich innych trybów uruchamiania lub jeśli ustawiono FLAG_ACTIVITY_SINGLE_TOP, to intencja zostanie dostarczona do onNewIntent () bieżącej instancji.


Tak więc,
1 . ZmienićlaunchMode działanie A na coś innego ze standardowego (np. singleTaskLub coś). Wtedy twoja flaga FLAG_ACTIVITY_CLEAR_TOPnie uruchomi ponownie Twojej Aktywności A.

lub,

2 . Użyj Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPjako swojej flagi. Wtedy będzie działać tak, jak chcesz.


8

Używam trzech flag, aby rozwiązać problem:

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

4

Dodaj android: noHistory = "true" w pliku manifestu.

<manifest >
        <activity
            android:name="UI"
            android:noHistory="true"/>

</manifest>

Pierwszy raz widzę tę flagę, ale zadziałała w moim przypadku, dzięki
vlasentiy

3

zadzwoniłem activity_name.this.finish()po rozpoczęciu nowej intencji i to zadziałało.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

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


2

Wiem, że istnieje już zaakceptowana odpowiedź, ale nie widzę, jak to działa w przypadku OP, ponieważ nie sądzę, aby FLAG_ACTIVITY_CLEAR_TOP miała sens w jego konkretnym przypadku. Ta flaga ma znaczenie tylko w przypadku działań w tym samym zadaniu . Opierając się na jego opisie, każda czynność ma swoje własne zadanie : A, B i przeglądarka.

Coś, co może go wytrącać, to fakt, że A to singleTop, podczas gdy powinno być singleTask. Jeśli A jest singleTop, a B zaczyna A, to zostanie utworzone nowe A, ponieważ A nie znajduje się w zadaniu B. Z dokumentacji dla singleTop:

„Jeśli instancja działania już istnieje na początku bieżącego zadania , system kieruje intencję do tej instancji…”

Ponieważ B rozpoczyna A, bieżące zadanie jest zadaniem B, które jest przeznaczone dla pojedynczej Instancji i dlatego nie może zawierać A. Użyj funkcji singleTask, aby osiągnąć tam pożądany rezultat, ponieważ wtedy system znajdzie zadanie, które ma A i przeniesie to zadanie na pierwszy plan.

Wreszcie, po tym, jak B uruchomił A, a użytkownik naciśnie z powrotem z A, OP nie chce widzieć ani B, ani przeglądarki. Aby to osiągnąć, wywołanie finish () w B jest poprawne; ponownie FLAG_ACTIVITY_CLEAR_TOP nie usunie innych działań z zadania A, ponieważ wszystkie jego pozostałe działania należą do innych zadań. Brakowało mu jednak tego, że B powinien również używać FLAG_ACTIVITY_NO_HISTORY podczas odpalania intencji w przeglądarce. Uwaga: jeśli przeglądarka jest już uruchomiona jeszcze przed uruchomieniem aplikacji OP, to oczywiście zobaczysz przeglądarkę po naciśnięciu wstecz z A. Aby naprawdę to przetestować, wyjdź z przeglądarki przed uruchomieniem aplikacji.


1

FLAG_ACTIVITY_NEW_TASK jest tutaj problemem, który inicjuje nowe zadanie. Po prostu je usuń i gotowe.

Cóż, polecam przeczytać, co robi każda flaga przed rozpoczęciem pracy z nimi

Przeczytaj to & Flagi intencji tutaj


1
Przeczytałem flagę i brzmiało jak to, czego potrzebowałem. Niezależnie od tego, usunięcie FLAG_ACTIVITY_NEW_TASK nie ma wpływu na wynik. To wciąż niekończąca się pętla przycisku wstecz ... A-> B, z powrotem do A, z powrotem do B, z powrotem do A ...
piusvelte

Czy jesteś pewien, dlaczego używasz B jako singleInstance? Aktywność AA „singleInstance” działa tak, jakby FLAG_ACTIVITY_NEW_TASK była w intencji. Sprawdź developer.android.com/guide/topics/fundamentals.html
100rabg

B musi otrzymać intencję oddzwonioną z przeglądarki. Próbowałem zmienić tryb uruchamiania na singleTask i to nadal działa, ale nadal występuje pętla przycisku Wstecz.
piusvelte

Myślę, że to nie zadziałało, ponieważ użyłeś tam FLAG_ACTIVITY_NEW_TASK Lepiej używaj tylko FLAG_ACTIVITY_CLEAR_TOP i unikaj używania ani singleTask, ani singleInstance
100rabh

1
Myślę, że powinno to być działające rozwiązanie, jeśli dodasz, Intent.FLAG_ACTIVITY_SINGLE_TOPaby zapobiec odtworzeniu
yonojoy

1

Na początku miałem też problem z uruchomieniem FLAG_ACTIVITY_CLEAR_TOP. W końcu udało mi się go uruchomić, używając jego wartości (0x04000000). Wygląda na to, że wystąpił problem z Eclipse / kompilatorem. Ale niestety aktywność, która przetrwała, zostaje wznowiona, co nie jest tym, czego chcę. Wygląda na to, że nie ma łatwego rozwiązania.

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.