Próbuję napisać aplikację, która robi coś konkretnego, gdy po pewnym czasie zostanie przywrócona na pierwszy plan. Czy istnieje sposób na wykrycie, kiedy aplikacja zostanie wysłana w tło lub przeniesiona na pierwszy plan?
android
background
foreground
iHorse
źródło
źródło
Odpowiedzi:
onPause()
IonResume()
metody są wywoływane, gdy aplikacja jest prawidłowe tle i na pierwszym planie ponownie. Są one jednak wywoływane również przy pierwszym uruchomieniu aplikacji i przed jej zabiciem. Więcej możesz przeczytać w Aktywności .Nie ma bezpośredniego podejścia do uzyskania statusu aplikacji w tle lub na pierwszym planie, ale nawet ja napotkałem ten problem i znalazłem rozwiązanie za pomocą
onWindowFocusChanged
ionStop
.Aby uzyskać więcej informacji, sprawdź tutaj Android: Rozwiązanie pozwalające wykryć, kiedy aplikacja na Androida przechodzi w tło i wraca na pierwszy plan bez getRunningTasks lub getRunningAppProcesses .
źródło
2018: Android obsługuje to natywnie poprzez komponenty cyklu życia.
AKTUALIZACJA z marca 2018 r . : Istnieje teraz lepsze rozwiązanie. Zobacz ProcessLifecycleOwner . Będziesz musiał korzystać z nowych komponentów architektury 1.1.0 (najnowsza w tej chwili), ale jest to konkretnie zaprojektowane do tego celu.
W tej odpowiedzi podano prosty przykład, ale napisałem przykładową aplikację i post na blogu o nim.
Odkąd napisałem to w 2014 roku, pojawiły się różne rozwiązania. Niektórzy pracowali, niektóre były uważane pracować , ale miał wady (w tym moje!), A my, jako wspólnota (Android) nauczył się żyć z konsekwencjami i napisał obejścia szczególnych przypadkach.
Nigdy nie zakładaj, że pojedynczy fragment kodu jest rozwiązaniem, którego szukasz, jest mało prawdopodobne; jeszcze lepiej, spróbuj zrozumieć, co robi i dlaczego to robi.
MemoryBoss
Klasa nigdy nie był rzeczywiście używany przeze mnie napisane, że to tylko kawałek pseudo kod, co wydarzyło się do pracy.O ile nie ma uzasadnionego powodu, abyś nie korzystał z nowych komponentów architektury (a są takie, szczególnie jeśli celujesz w super stare api), to idź dalej i używaj ich. Są dalekie od ideału, ale żadne z nich nie było
ComponentCallbacks2
.AKTUALIZACJA / UWAGI (listopad 2015) : Ludzie piszą dwa komentarze, po pierwsze,
>=
należy ich użyć zamiast,==
ponieważ dokumentacja stwierdza, że nie należy sprawdzać dokładnych wartości . W większości przypadków jest to w porządku, ale pamiętaj, że jeśli zależy Ci tylko na zrobieniu czegoś, gdy aplikacja przeszła w tło, będziesz musiał użyć == i również połączyć to z innym rozwiązaniem (np. Wywołania zwrotne cyklu życia) lub może nie uzyskać pożądanego efektu. Przykład (i to mi się przydarzyło) jest taki, że jeśli chcesz zablokowaćTwoja aplikacja z ekranem z hasłem, gdy przechodzi w tło (np. 1 Hasło, jeśli ją znasz), możesz przypadkowo zablokować aplikację, jeśli zabraknie pamięci i nagle zaczniesz testować>= TRIM_MEMORY
, ponieważ Android uruchomiLOW MEMORY
połączenie, a to wyższy niż twój. Więc bądź ostrożny jak / co testujesz.Ponadto niektóre osoby pytały o sposób wykrywania po powrocie.
Najprostszy sposób, jaki mogę wymyślić, wyjaśniono poniżej, ale ponieważ niektórzy ludzie nie są z tym zaznajomieni, dodam tutaj pseudo kod. Zakładając, że masz
YourApplication
iMemoryBoss
klasy, w swoimclass BaseActivity extends Activity
(musisz je utworzyć, jeśli go nie masz).Polecam onStart, ponieważ okna dialogowe mogą wstrzymywać aktywność, więc założę się, że nie chcesz, aby twoja aplikacja myślała „poszła do tła”, jeśli wszystko co zrobiłeś, to wyświetlało okno dialogowe na pełnym ekranie, ale przebieg może się różnić.
I to wszystko. Kod w bloku if zostanie wykonany tylko raz , nawet jeśli przejdziesz do innego działania, nowe (to także
extends BaseActivity
) zgłosiwasInBackground
to,false
aby nie wykonało kodu, dopóki nieonMemoryTrimmed
zostanie wywołane, a flaga ponownie ustawiona na true .Mam nadzieję, że to pomaga.
AKTUALIZACJA / UWAGI (kwiecień 2015 r.) : Zanim przejdziesz do wszystkich funkcji Kopiuj i Wklej ten kod, zauważ, że znalazłem kilka przypadków, w których może on nie być w 100% wiarygodny i musi być połączony z innymi metodami, aby uzyskać najlepsze wyniki. W szczególności istnieją dwa znane przypadki, w których
onTrimMemory
nie można zagwarantować, że oddzwonienie zostanie wykonane:Jeśli telefon blokuje ekran, gdy aplikacja jest widoczna (powiedzmy, że urządzenie blokuje się po nn minutach), to wywołanie zwrotne nie jest wywoływane (lub nie zawsze), ponieważ ekran blokady jest na samej górze, ale aplikacja jest nadal „uruchomiona”, chociaż jest zakryta.
Jeśli twoje urządzenie ma stosunkowo mało pamięci (i jest pod obciążeniem pamięci), system operacyjny wydaje się ignorować to połączenie i przechodzi bezpośrednio do bardziej krytycznych poziomów.
Teraz, w zależności od tego, jak ważne jest, aby wiedzieć, kiedy aplikacja przeszła do tła, może być konieczne rozszerzenie tego rozwiązania wraz ze śledzeniem cyklu życia aktywności i tym podobne.
Pamiętaj o tym i miej dobry zespół kontroli jakości;)
KONIEC AKTUALIZACJI
Może być późno, ale istnieje niezawodna metoda w Ice Cream Sandwich (API 14) i wyżej .
Okazuje się, że gdy aplikacja nie ma już widocznego interfejsu użytkownika, wywoływane jest oddzwanianie. Oddzwonienie, które można zaimplementować w klasie niestandardowej, nazywa się ComponentCallbacks2 (tak, z dwójką). To wywołanie zwrotne jest dostępne tylko na poziomie API 14 (Ice Cream Sandwich) i wyższym.
Zasadniczo otrzymujesz wywołanie metody:
Poziom wynosi 20 lub więcej
Testowałem to i zawsze działa, ponieważ poziom 20 to tylko „sugestia”, że możesz chcieć zwolnić część zasobów, ponieważ Twoja aplikacja nie jest już widoczna.
Cytując oficjalne dokumenty:
Oczywiście, powinieneś to zaimplementować, aby faktycznie zrobić to, co mówi (oczyść pamięć, która nie była używana przez pewien czas, wyczyść niektóre zbiory, które nie były używane itp. Możliwości są nieograniczone (zobacz oficjalne dokumenty, aby uzyskać więcej możliwych poziomy krytyczne ).
Ale interesujące jest to, że system operacyjny mówi: HEJ, twoja aplikacja poszła w tło!
Właśnie to przede wszystkim chciałeś wiedzieć.
Jak ustalić, kiedy wróciłeś?
Cóż, to proste, jestem pewien, że masz „BaseActivity”, dzięki czemu możesz użyć funkcji onResume () do oznaczenia faktu powrotu. Ponieważ jedyny raz, kiedy powiesz, że nie wróciłeś, to faktyczne otrzymanie połączenia z powyższą
onTrimMemory
metodą.To działa. Nie otrzymujesz fałszywych trafień. Jeśli aktywność zostanie wznowiona, wrócisz 100% razy. Jeśli użytkownik ponownie przejdzie do tyłu, otrzymasz kolejne
onTrimMemory()
połączenie.Musisz opisać swoje działania (lub jeszcze lepiej niestandardową klasę).
Najłatwiejszym sposobem na zagwarantowanie, że zawsze to otrzymasz, jest utworzenie prostej klasy takiej jak ta:
Aby tego użyć, we wdrożeniu aplikacji ( masz RIGHT? ), Wykonaj coś takiego:
Jeśli utworzysz,
Interface
możesz dodaćelse
do niegoif
i zaimplementowaćComponentCallbacks
(bez 2) używane w czymkolwiek poniżej API 14. To wywołanie zwrotne ma tylkoonLowMemory()
metodę i nie jest wywoływane, gdy przejdziesz do tła , ale powinieneś użyć go do przycięcia pamięci .Teraz uruchom aplikację i naciśnij przycisk home. Twoja
onTrimMemory(final int level)
metoda powinna zostać wywołana (wskazówka: dodaj rejestrowanie).Ostatnim krokiem jest wyrejestrowanie się z oddzwaniania. Prawdopodobnie najlepszym miejscem jest
onTerminate()
metoda Twojej aplikacji, ale ta metoda nie jest wywoływana na prawdziwym urządzeniu:Tak więc, chyba że naprawdę masz sytuację, w której nie chcesz już być rejestrowanym, możesz bezpiecznie zignorować to, ponieważ proces i tak umiera na poziomie systemu operacyjnego.
Jeśli w pewnym momencie zdecydujesz się wyrejestrować (jeśli na przykład zapewnisz mechanizm zamykania aplikacji, aby wyczyścić i umrzeć), możesz:
I to wszystko.
źródło
level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
co pozwala uniknąć problemu w twojej aktualizacji, punkt 2. Jeśli chodzi o punkt 1, nie jest to dla mnie problemem, ponieważ aplikacja tak naprawdę nie poszła w tło, więc tak powinna działać.Oto jak udało mi się to rozwiązać. Działa przy założeniu, że użycie odniesienia czasowego między przejściami aktywności najprawdopodobniej dostarczy wystarczających dowodów na to, że aplikacja została „uruchomiona w tle” lub nie.
Po pierwsze, użyłem instancji android.app.Application (nazwijmy ją MyApplication), która ma Timer, TimerTask, stałą reprezentującą maksymalną liczbę milisekund, jaką przejście z jednej czynności do drugiej może rozsądnie zająć (poszedłem o wartości 2s) i wartość logiczną wskazującą, czy aplikacja była „w tle”:
Aplikacja udostępnia również dwie metody uruchamiania i zatrzymywania stopera / zadania:
Ostatnim elementem tego rozwiązania jest dodanie wywołania do każdej z tych metod ze zdarzeń onResume () i onPause () wszystkich działań lub, najlepiej, działania podstawowego, z którego dziedziczą wszystkie konkretne działania:
Tak więc w przypadku, gdy użytkownik po prostu porusza się między działaniami aplikacji, funkcja onPause () czynności odchodzącej uruchamia stoper, ale prawie natychmiast nowa wprowadzona aktywność anuluje stoper, zanim osiągnie maksymalny czas przejścia. I tak wasInBackground byłoby fałszywe .
Z drugiej strony, gdy działanie pojawia się na pierwszym planie z poziomu Launchera, wybudzanie urządzenia, kończenie połączenia telefonicznego itp., Bardziej niż prawdopodobne, że zadanie timera wykonane przed tym zdarzeniem, a tym samym parametr wasInBackground został ustawiony na wartość true .
źródło
Edycja: nowe komponenty architektury przyniosły coś obiecującego: ProcessLifecycleOwner , patrz odpowiedź @ vokilam
Rzeczywiste rozwiązanie według rozmowy Google I / O :
Tak. Wiem, że trudno uwierzyć, że to proste rozwiązanie działa, ponieważ mamy tutaj tak wiele dziwnych rozwiązań.
Ale jest nadzieja.
źródło
ProcessLifecycleOwner
wydaje się również obiecującym rozwiązaniem.Implementacja może być tak prosta jak
Zgodnie z kodem źródłowym bieżąca wartość opóźnienia wynosi
700ms
.Korzystanie z tej funkcji wymaga również
dependencies
:źródło
implementation "android.arch.lifecycle:extensions:1.0.0"
orazannotationProcessor "android.arch.lifecycle:compiler:1.0.0"
z repozytorium Google (tj.google()
)Na podstawie odpowiedzi Martína Marconcinisa (dzięki!) W końcu znalazłem niezawodne (i bardzo proste) rozwiązanie.
Następnie dodaj to do swojej klasy onCreate () swojej klasy aplikacji
źródło
Używamy tej metody. Wygląda na zbyt prostą do pracy, ale została dobrze przetestowana w naszej aplikacji i w rzeczywistości działa zaskakująco dobrze we wszystkich przypadkach, w tym przechodzenie do ekranu głównego za pomocą przycisku „home”, przycisku „powrót” lub po zablokowaniu ekranu. Spróbuj.
Chodzi o to, że na pierwszym planie Android zawsze rozpoczyna nową aktywność tuż przed zatrzymaniem poprzedniej. Nie jest to gwarantowane, ale tak to działa. BTW, Flurry zdaje się używać tej samej logiki (zgaduję, że tego nie sprawdziłem, ale dotyczy to tych samych zdarzeń).
Edycja: zgodnie z komentarzami przenieśliśmy się również do onStart () w późniejszych wersjach kodu. Dodam też super wywołania, których brakowało w moim początkowym poście, ponieważ była to raczej koncepcja niż działający kod.
źródło
onStop is called when the activity is no longer visible to the user
.Jeśli aplikacja składa się z wielu działań i / lub działań ułożonych w stos, takich jak widget paska kart, zastąpienie funkcji onPause () i onResume () nie będzie działać. Tzn. Przy rozpoczynaniu nowej działalności bieżące działania zostaną wstrzymane przed utworzeniem nowej. To samo dotyczy zakończenia (korzystania z przycisku „wstecz”) działania.
Znalazłem dwie metody, które wydają się działać zgodnie z oczekiwaniami.
Pierwszy wymaga uprawnienia GET_TASKS i składa się z prostej metody, która sprawdza, czy najczęściej działająca aktywność na urządzeniu należy do aplikacji, poprzez porównanie nazw pakietów:
Ta metoda została znaleziona w frameworku Droid-Fu (obecnie nazywanym Ignition).
Druga metoda, którą zaimplementowałem, nie wymaga pozwolenia GET_TASKS, co jest dobre. Zamiast tego wdrożenie jest nieco bardziej skomplikowane.
W swojej klasie MainApplication masz zmienną, która śledzi liczbę uruchomionych działań w aplikacji. W onResume () dla każdego działania zwiększasz zmienną, a w onPause () ją zmniejszasz.
Gdy liczba uruchomionych działań osiągnie wartość 0, aplikacja zostanie umieszczona w tle, JEŻELI następujące warunki są spełnione:
Gdy możesz wykryć, że aplikacja zrezygnowała z pracy w tle, łatwo jest również wykryć, kiedy zostanie przywrócona na pierwszy plan.
źródło
getRunnintTasks()
Utwórz klasę, która się rozszerza
Application
. Następnie w nim możemy wykorzystać jego metodę obejścia,onTrimMemory()
.Aby wykryć, czy aplikacja przeszła w tło, użyjemy:
źródło
FragmentActivity
także chcieć dodaćlevel == ComponentCallbacks2.TRIM_MEMORY_COMPLETE
też.Rozważ użycie onUserLeaveHint. Zostanie to wywołane tylko wtedy, gdy aplikacja przejdzie w tło. onPause będzie obsługiwał przypadki narożne, ponieważ można je wywoływać z innych powodów; na przykład, jeśli użytkownik otworzy inne działanie w Twojej aplikacji, takie jak strona ustawień, metoda onPause głównej aktywności zostanie wywołana, nawet jeśli nadal jest w Twojej aplikacji; śledzenie tego, co się dzieje, doprowadzi do błędów, gdy zamiast tego możesz po prostu użyć wywołania zwrotnego onUserLeaveHint, które robi to, o co prosisz.
Gdy wywoływana jest funkcja UserLeaveHint, można ustawić wartość logiczną inBackground na wartość true. Po wywołaniu onResume zakładaj, że wróciłeś na pierwszy plan, jeśli ustawiona jest flaga inBackground. Wynika to z faktu, że onResume będzie również wywoływany w przypadku głównej aktywności, jeśli użytkownik był tylko w menu ustawień i nigdy nie opuścił aplikacji.
Pamiętaj, że jeśli użytkownik naciśnie przycisk Home na ekranie ustawień, onUserLeaveHint zostanie wywołany w ustawieniach, a gdy wróci, Resum zostanie wywołany w ustawieniach. Jeśli masz tylko ten kod wykrywający w głównej działalności, przegapisz ten przypadek użycia. Aby mieć ten kod we wszystkich twoich działaniach bez powielania kodu, przygotuj abstrakcyjną klasę aktywności, która rozszerza działanie i umieść w nim swój wspólny kod. Następnie każde działanie, które masz, może rozszerzyć to działanie abstrakcyjne.
Na przykład:
źródło
ActivityLifecycleCallbacks może być interesujące, ale nie jest dobrze udokumentowane.
Jednak jeśli wywołasz registerActivityLifecycleCallbacks (), powinieneś być w stanie uzyskać wywołania zwrotne, gdy Działania są tworzone, niszczone itp. Możesz wywołać getComponentName () dla Działania.
źródło
Android.arch.lifecycle pakiet zawiera klasy i interfejsy, które pozwalają budować elementy cyklu życia-aware
Twoja aplikacja powinna implementować interfejs LifecycleObserver:
Aby to zrobić, musisz dodać tę zależność do pliku build.gradle:
Zgodnie z zaleceniami Google należy zminimalizować kod wykonywany w metodach cyklu życia działań:
Możesz przeczytać więcej tutaj: https://developer.android.com/topic/libraries/architecture/lifecycle
źródło
W swojej aplikacji dodaj wywołanie zwrotne i sprawdź aktywność roota w następujący sposób:
źródło
Stworzyłem projekt na Github app-foreground-background-listen
Utwórz BaseActivity dla wszystkich działań w aplikacji.
Teraz użyj tej funkcji BaseActivity jako superklasy wszystkich działań, takich jak MainActivity rozszerza funkcję BaseActivity, a onAppStart będzie wywoływany przy uruchamianiu aplikacji, a onAppPause () będzie wywoływany, gdy aplikacja przejdzie w tło z dowolnego ekranu.
źródło
To jest dość łatwe ProcessLifecycleOwner
Dodaj te zależności
W Kotlinie :
Następnie w swojej podstawowej aktywności:
Zobacz mój artykuł na ten temat: https://medium.com/@egek92/how-to-actally-detect-foreground-background-changes-in-your-android-application-with-wanting-9719cc822c48
źródło
Możesz użyć ProcessLifecycleOwner dołączając do niego obserwatora cyklu życia.
następnie w
onCreate()
swojej klasie aplikacji nazywasz to:Dzięki temu będziesz w stanie uchwycić zdarzenia
ON_PAUSE
iON_STOP
aplikacji, które mają miejsce, gdy przejdzie ona w tło.źródło
Nie ma prostych metod cyklu życia, które informują, kiedy cała aplikacja przechodzi w tło / na pierwszym planie.
Zrobiłem to w prosty sposób. Postępuj zgodnie z poniższymi instrukcjami, aby wykryć fazę tła aplikacji / pierwszego planu.
Przy odrobinie obejścia jest to możliwe. Tutaj na ratunek przychodzi ActivityLifecycleCallback . Pozwól mi przejść krok po kroku.
Najpierw utwórz klasę, która rozszerza aplikację android.app.Application i implementuje interfejs ActivityLifecycleCallbacks . W Application.onCreate () zarejestruj wywołanie zwrotne.
Zarejestruj klasę „APP” w manifeście jak poniżej
<application android:name=".App"
.Gdy aplikacja będzie na pierwszym planie, będzie co najmniej jedna aktywność w stanie uruchomionym, a nie będzie żadnej aktywności w stanie uruchomionym, gdy aplikacja będzie w tle.
Zadeklaruj 2 zmienne jak poniżej w klasie „App”.
activityReferences
zachowa liczbę działań w stanie uruchomionym .isActivityChangingConfigurations
to flaga wskazująca, czy bieżąca aktywność przechodzi zmianę konfiguracji, jak przełącznik orientacji.Za pomocą następującego kodu możesz sprawdzić, czy aplikacja jest na pierwszym planie.
W ten sposób można wykryć, czy aplikacja przechodzi w tło.
Jak to działa:
Jest to mała sztuczka zrobiona ze sposobem, w jaki metody cyklu życia są wywoływane kolejno. Pozwól mi przejść przez scenariusz.
Załóżmy, że użytkownik uruchamia aplikację i uruchamiane jest działanie A dotyczące uruchamiania. Połączenia cyklu życia będą,
Teraz działanie A rozpoczyna działanie B.
Następnie użytkownik wraca z działania B,
Następnie użytkownik naciska przycisk Home,
W przypadku, gdy użytkownik naciśnie przycisk Początek z działania B zamiast przycisku Wstecz, nadal będzie taki sam, a aktywność Odniesienia będą
0
. Dlatego możemy wykryć, że aplikacja wchodzi w tło.Jaka jest więc rola
isActivityChangingConfigurations
? W powyższym scenariuszu załóżmy, że działanie B zmienia orientację. Sekwencja oddzwonienia będzieDlatego mamy dodatkowe sprawdzenie,
isActivityChangingConfigurations
aby uniknąć scenariusza, w którym działanie przechodzi zmiany konfiguracji.źródło
Znalazłem dobrą metodę wykrywania aplikacji, bez względu na to, czy wchodzi na pierwszy plan, czy w tło. Oto mój kod . Mam nadzieję, że ci to pomoże.
}
źródło
Możesz użyć:
Różnicowanie między nowymi uruchomieniami i restartami.
źródło
Edycja 2: To, co napisałem poniżej, nie zadziała. Google odrzucił aplikację, która zawiera wywołanie ActivityManager.getRunningTasks (). Z dokumentacji wynika, że ten interfejs API służy wyłącznie do debugowania i programowania. Będę aktualizować ten post, jak tylko będę mieć czas, aby zaktualizować poniższy projekt GitHub o nowy schemat, który używa timerów i jest prawie tak dobry.
Edycja 1: Napisałem wpis na blogu i utworzyłem proste repozytorium GitHub, aby było to naprawdę łatwe.
Zarówno zaakceptowana, jak i najwyżej oceniana odpowiedź nie są najlepszym podejściem. Implementacja najwyżej ocenionej odpowiedzi isApplicationBroughtToBackground () nie obsługuje sytuacji, w której główna aktywność aplikacji ulega działaniu zdefiniowanemu w tej samej aplikacji, ale ma inny pakiet Java. Wymyśliłem sposób, aby to zrobić, co zadziała w tym przypadku.
Wywołaj to w funkcji onPause (), a dowiesz się, czy aplikacja przechodzi w tło, ponieważ uruchomiono inną aplikację, czy użytkownik nacisnął przycisk Home.
źródło
Prawidłowa odpowiedź tutaj
Utwórz klasę o nazwie MyApp jak poniżej:
Następnie, gdziekolwiek chcesz (lepsza pierwsza aktywność uruchomiona w aplikacji), dodaj poniższy kod:
Gotowy! Teraz, gdy aplikacja jest w tle, otrzymujemy dziennik,
status : we are out
a kiedy wchodzimy do aplikacji, otrzymujemy dziennikstatus : we are out
źródło
Moje rozwiązanie zostało zainspirowane odpowiedzią @ d60402, a także opiera się na oknie czasowym, ale nie używa
Timer
:gdzie
SingletonApplication
jest rozszerzeniemApplication
klasy:źródło
Korzystałem z tego w Google Analytics EasyTracker i działało. Można to rozszerzyć, aby robić to, czego szukasz, używając prostej liczby całkowitej.
źródło
wiem, że jest trochę późno, ale myślę, że wszystkie te odpowiedzi mają pewne problemy, podczas gdy zrobiłem to jak poniżej i działa to idealnie.
utwórz wywołanie zwrotne cyklu życia działania w następujący sposób:
i po prostu zarejestruj go w swojej klasie aplikacji, jak poniżej:
źródło
To wydaje się być jednym z najbardziej skomplikowanych pytań w Androidzie, ponieważ (od tego momentu) Android nie ma odpowiedników iOS
applicationDidEnterBackground()
aniapplicationWillEnterForeground()
wywołań zwrotnych. Kiedyś Biblioteka AppState która została stworzona przez @jenzz .Okazało się, że tego właśnie potrzebowałem, szczególnie dlatego, że moja aplikacja miała wiele działań, więc po prostu sprawdzenie
onStart()
lubonStop()
aktywność nie zamierzała go wyciąć.Najpierw dodałem te zależności do stopniowania:
Następnie wystarczyło dodać te wiersze do odpowiedniego miejsca w kodzie:
W zależności od tego, w jaki sposób subskrybujesz obserwowalne, może być konieczne anulowanie subskrypcji, aby uniknąć wycieków pamięci. Ponownie więcej informacji na stronie github .
źródło
To jest zmodyfikowana wersja odpowiedzi @ d60402: https://stackoverflow.com/a/15573121/4747587
Rób wszystko, co tam wspomniano. Ale zamiast mieć
Base Activity
i nadać temu status nadrzędny dla każdego działania i zastąpićonResume()
ionPause
, wykonaj następujące czynności:W swojej klasie aplikacji dodaj wiersz:
registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks);
Ma
callback
to wszystkie metody cyklu życia aktywności i możesz teraz zastąpićonActivityResumed()
ionActivityPaused()
.Spójrz na tę Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b
źródło
Możesz to łatwo osiągnąć za pomocą
ActivityLifecycleCallbacks
iComponentCallbacks2
czegoś takiego jak poniżej.Utwórz klasę
AppLifeCycleHandler
implementującą powyższe interfejsy.W twojej klasie, która rozszerza
Application
implementację,AppLifeCycleCallback
aby uzyskać wywołania zwrotne, gdy aplikacja przełącza się między pierwszym planem a tłem. Coś jak poniżej.Mam nadzieję że to pomoże.
EDYCJA Jako alternatywę możesz teraz użyć komponentu architektury uwzględniającej cykl życia.
źródło
Ponieważ nie znalazłem żadnego podejścia, które obsługuje rotację bez sprawdzania znaczników czasu, pomyślałem, że podzielę się również tym, jak teraz to robimy w naszej aplikacji. Jedynym dodatkiem do tej odpowiedzi https://stackoverflow.com/a/42679191/5119746 jest to, że uwzględniamy również orientację.
Następnie dla oddzwaniania najpierw mamy CV:
I onActivityStopped:
A potem pojawia się dodatek: Sprawdzanie zmian orientacji:
Otóż to. Mam nadzieję, że to komuś pomoże :)
źródło
Możemy rozwinąć to rozwiązanie za pomocą
LiveData
:Teraz możemy zasubskrybować tę LiveData i złapać potrzebne zdarzenia. Na przykład:
źródło
Te odpowiedzi wydają się nieprawidłowe. Te metody są również wywoływane, gdy rozpoczyna się i kończy inna aktywność. Możesz zachować flagę globalną (tak, globały są złe :) i ustaw ją na wartość true za każdym razem, gdy zaczynasz nową aktywność. Ustaw wartość false w polu onCreate każdego działania. Następnie w onPause sprawdzasz tę flagę. Jeśli jest to fałsz, aplikacja przechodzi w tło lub ginie.
źródło