Wszystkie działania w mojej aplikacji wymagają zalogowania użytkownika, aby wyświetlić. Użytkownicy mogą wylogować się z niemal każdej aktywności. Jest to wymóg aplikacji. W dowolnym momencie, jeśli użytkownik wyloguje się, chcę wysłać użytkownika do Loginu Activity
. W tym momencie chcę, aby ta aktywność była na dole stosu historii, więc naciśnięcie przycisku „wstecz” powoduje powrót użytkownika do ekranu głównego Androida.
Widziałem to pytanie zadane w kilku różnych miejscach, na wszystkie odpowiedziały podobne odpowiedzi (które tutaj zarysowuję), ale chcę je zadać tutaj, aby zebrać opinie.
Próbowałem otworzyć działanie logowania, ustawiając jego Intent
flagi, FLAG_ACTIVITY_CLEAR_TOP
które wydają się robić tak, jak opisano w dokumentacji, ale nie osiągam celu, jakim jest umieszczenie działania logowania na dole stosu historii i uniemożliwienie użytkownikowi powrotu do poprzedniej strony do wcześniej zarejestrowanych zalogowanych działań. Próbowałem również użyć android:launchMode="singleTop"
do zalogowania się w manifeście, ale to również nie osiąga mojego celu (i wydaje się, że i tak nie ma żadnego efektu).
Uważam, że muszę wyczyścić stos historii lub zakończyć wszystkie wcześniej otwarte działania.
Jedną z opcji jest onCreate
status kontroli każdego działania zalogowany, a finish()
jeśli nie zalogowany. Nie podoba mi się ta opcja, ponieważ przycisk Wstecz będzie nadal dostępny do użycia, nawigując wstecz w miarę zamykania się działań.
Kolejną opcją jest utrzymanie a LinkedList
odniesień do wszystkich otwartych działań, które są dostępne statycznie zewsząd (być może przy użyciu słabych odniesień). Po wylogowaniu uzyskam dostęp do tej listy i powtarzam wszystkie wcześniej otwarte działania, wywołując finish()
każdą z nich. Prawdopodobnie zacznę wkrótce wdrażać tę metodę.
Wolę jednak użyć pewnych Intent
sztuczek z flagą, aby to osiągnąć. Z przyjemnością stwierdzę, że mogę spełnić wymagania mojej aplikacji bez konieczności korzystania z jednej z dwóch opisanych powyżej metod.
Czy istnieje sposób na osiągnięcie tego poprzez użycie Intent
lub manifestowanie ustawień, czy też moja druga opcja, utrzymywanie LinkedList
otwartych działań, jest najlepszą opcją? Czy jest jeszcze inna opcja, którą całkowicie pomijam?
Wydaje się, że nowy programista dla Androida spędza dzień na badaniu tego problemu i czytaniu wszystkich wątków StackOverflow. Jestem teraz nowo wtajemniczony i zostawiam tutaj ślad mojego skromnego doświadczenia, aby pomóc przyszłemu pielgrzymowi.
Po pierwsze, nie ma oczywistego ani bezpośredniego sposobu, aby to zrobić na podstawie moich badań.
(as of September 2012).
Można by pomyśleć, że można to zrobić w prosty sposób,startActivity(new Intent(this, LoginActivity.class), CLEAR_STACK)
ale nie .MOŻESZ zrobić
startActivity(new Intent(this, LoginActivity.class))
zFLAG_ACTIVITY_CLEAR_TOP
- a to spowoduje, że framework przeszuka stos, odszuka wcześniejszą instancję LoginActivity, odtworzy ją i wyczyści resztę stosu (w górę). A ponieważ Login prawdopodobnie znajduje się na dole stosu, masz teraz pusty stos, a przycisk Wstecz tylko wychodzi z aplikacji.ALE - działa to tylko wtedy, gdy wcześniej pozostawiłeś żywy egzemplarz LoginActivity u podstawy stosu. Jeśli, podobnie jak wielu programistów, wybrałeś
finish()
toLoginActivity
po pomyślnym zalogowaniu się użytkownika, nie jest on już oparty na stosie iFLAG_ACTIVITY_CLEAR_TOP
semantyka nie ma zastosowania ... w końcu tworzysz nowyLoginActivity
na istniejącym stosie. Co prawie na pewno NIE jest tym, czego chcesz (dziwne zachowanie, w którym użytkownik może „cofnąć się” po zalogowaniu do poprzedniego ekranu).Więc jeśli już
finish()
toLoginActivity
zrobiłeś, musisz zastosować jakiś mechanizm, aby wyczyścić swój stos, a następnie rozpocząć nowyLoginActivity
. Wydaje się, że odpowiedź@doreamon
w tym wątku jest najlepszym rozwiązaniem (przynajmniej moim skromnym okiem):https://stackoverflow.com/a/9580057/614880
Podejrzewam, że skomplikowane konsekwencje pozostawienia przy życiu LoginActivity powodują wiele zamieszania.
Powodzenia.
źródło
AKTUALIZACJA
super
finishAffinity()
metoda pomoże zredukować kod, ale osiągnie to samo. Zakończy bieżącą aktywność, a także wszystkie działania na stosie, użyj,getActivity().finishAffinity()
jeśli jesteś we fragmencie.ORYGINALNA ODPOWIEDŹ
Załóżmy, że LoginActivity -> HomeActivity -> ... -> SettingsActivity call callOut ():
HomeActivity:
To działa dla mnie, mam nadzieję, że to też jest pomocne. :)
źródło
Jeśli używasz interfejsu API 11 lub nowszego, możesz spróbować: -
FLAG_ACTIVITY_CLEAR_TASK
wydaje się, że rozwiązuje dokładnie ten sam problem. Oczywiście tłum przed API 11 musiałby użyć kombinacji sprawdzania wszystkich działań dodatkowo, jak sugeruje @doreamon, lub innej sztuczki.(Uwaga: aby z tego skorzystać, musisz przekazać
FLAG_ACTIVITY_NEW_TASK
)źródło
finish();
wykonam zadanie, aby zapobiec powrotowi po wylogowaniu. Po co ustawiać flagi?Spędziłem nad tym także kilka godzin ... i zgadzam się, że FLAG_ACTIVITY_CLEAR_TOP brzmi tak, jakbyś chciał: wyczyść cały stos, z wyjątkiem uruchomionej aktywności, więc przycisk Wstecz wychodzi z aplikacji. Jednak, jak wspomniał Mike Repass , FLAG_ACTIVITY_CLEAR_TOP działa tylko wtedy, gdy aktywność, którą uruchamiasz, znajduje się już na stosie; gdy działania nie ma, flaga nic nie robi.
Co robić? Umieść uruchamiane działanie w stosie za pomocą FLAG_ACTIVITY_NEW_TASK , co powoduje, że działanie to rozpoczyna nowe zadanie na stosie historii. Następnie dodaj flagę FLAG_ACTIVITY_CLEAR_TOP.
Teraz, gdy FLAG_ACTIVITY_CLEAR_TOP pójdzie znaleźć nową aktywność na stosie, będzie tam i zostanie podniesiona, zanim wszystko inne zostanie wyczyszczone.
Oto moja funkcja wylogowania; parametr View to przycisk, do którego dołączona jest funkcja.
źródło
FLAG_ACTIVITY_CLEAR_TASK
nie został jeszcze dodanyWiele odpowiedzi. Być może ten pomoże również-
Wersja Kotlin
źródło
Użyj tego, to powinno ci pomóc. Nieznacznie zmodyfikowana odpowiedź xbakesx.
źródło
Zaakceptowane rozwiązanie jest nieprawidłowe, ma problemy, ponieważ używanie odbiornika nie jest dobrym pomysłem na ten problem. Jeśli twoja aktywność wywołała już metodę onDestroy (), nie otrzymasz odbiornika. Najlepszym rozwiązaniem jest ustawienie wartości logicznej na wspólnych preferencjach i sprawdzenie jej w metodzie onCreate () Twojej aktywności. Jeśli nie należy go wywoływać, gdy użytkownik nie jest zalogowany, zakończ działanie. Oto przykładowy kod do tego. Tak prosty i działa w każdych warunkach.
źródło
onResume()
. Ponieważ po naciśnięciu przycisku Wstecz działanie jest bardziej prawdopodobne, że zostanie wznowione niż utworzone.Czasami
finish()
nie działaRozwiązałem ten problem z
finishAffinity()
źródło
Sugerowałbym inne podejście do tego pytania. Może nie jest to najbardziej wydajny, ale myślę, że jest najłatwiejszy do zastosowania i wymaga bardzo małego kodu. Zapisanie następnego kodu w pierwszej aktywności (logowanie aktywności, w moim przypadku) nie pozwoli użytkownikowi powrócić do poprzednio uruchomionych działań po wylogowaniu.
Zakładam, że funkcja LoginActivity jest zakończona zaraz po zalogowaniu użytkownika, aby nie mógł do niej wrócić później, naciskając przycisk Wstecz. Zamiast tego użytkownik musi nacisnąć przycisk wylogowania w aplikacji, aby poprawnie się wylogować. To, co zastosowałby ten przycisk wylogowania, to prosta intencja:
Wszystkie sugestie są mile widziane.
źródło
Wybrana odpowiedź jest sprytna i podchwytliwa. Oto jak to zrobiłem:
LoginActivity jest główną aktywnością zadania, ustaw android: noHistory = "true" w Manifest.xml; Załóżmy, że chcesz się wylogować z Ustawień Aktywności, możesz to zrobić w następujący sposób:
źródło
Oto rozwiązanie, które wymyśliłem w mojej aplikacji.
W mojej LoginActivity, po pomyślnym przetworzeniu loginu, uruchamiam następny w różny sposób, w zależności od poziomu API.
Następnie w metodzie onActivityForResult mojej LoginActivity:
Wreszcie po przetworzeniu wylogowania w innym działaniu:
W przypadku Gingerbread sprawia, że jeśli kliknę przycisk Wstecz w MainActivity, LoginActivity zostanie natychmiast ukryty. W Honeycomb i nowszych właśnie kończę LoginActivity po przetworzeniu loginu i jest on poprawnie odtwarzany po przetworzeniu loginu.
źródło
To działało dla mnie:
źródło
Rozpocznij swoją aktywność za pomocą StartActivityForResult i podczas wylogowywania ustaw swój wynik i zgodnie z nim zakończ swoją aktywność
źródło
Podane rozwiązanie @doreamon działa dobrze we wszystkich przypadkach oprócz jednego:
Jeśli po zalogowaniu użytkownik ekranu Killing Login przejdzie bezpośrednio do środkowego ekranu. np. W strumieniu A-> B-> C nawiguj w następujący sposób: Zaloguj się -> B -> C -> Naciśnij skrót do strony głównej. Użycie FLAG_ACTIVITY_CLEAR_TOP usuwa tylko aktywność C, ponieważ strona główna (A) nie znajduje się w historii stosu. Naciśnięcie przycisku Wstecz na ekranie doprowadzi nas z powrotem do B.
Aby rozwiązać ten problem, możemy zachować stos aktywności (Arraylist), a gdy naciśniesz przycisk Home, musimy zabić wszystkie działania na tym stosie.
źródło
Jest to możliwe poprzez zarządzanie flagą w SharedPreferences lub w Aktywności aplikacji.
Po uruchomieniu aplikacji (na ekranie powitalnym) ustaw flag = false; W przypadku zdarzenia Logout Click wystarczy ustawić flagę true, a w OnResume () każdej aktywności sprawdzić, czy flaga jest true, a następnie wywołać metodę finish ().
To działa jak urok :)
źródło
po kliknięciu Wyloguj możesz to nazwać
onActivityResult () z poprzedniego działania wywołuje ten kod ponownie, dopóki nie zakończysz wszystkich działań.
źródło
To, co chcesz zrobić, to wywołanie funkcji wylogowania () i zakończenia () w metodach onStop () lub onPause (). Zmusi to Androida do wywołania funkcji onCreate () po przywróceniu działania, ponieważ nie będzie go już na stosie działania. Następnie rób, co mówisz, w onCreate () sprawdź status zalogowanego użytkownika i przejdź do ekranu logowania, jeśli nie jesteś zalogowany.
Inną rzeczą, którą możesz zrobić, to sprawdzić status zalogowanego w onResume (), a jeśli nie zalogowany, zakończ () i uruchom aktywność logowania.
źródło