applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

215

Który delegat jest odpowiedni do wdrożenia, gdy aplikacja budzi się z tła i chcesz, aby była przygotowana do działania?

applicationWillEnterForeground vs. applicationDidBecomeActive - Jaka jest różnica?

Który delegat jest odpowiedni do wdrożenia, gdy aplikacja będzie spać i chcesz przygotować ją do czyszczenia i zapisywania danych?

applicationWillResignActive vs. applicationDidEnterBackground - Jaka jest różnica?

Zauważyłem również, że applicationWillResignActive jest wywoływany, gdy przychodzi SMS lub połączenie przychodzące, ale użytkownik decyduje się kliknąć OK i kontynuować. W tych przypadkach nie chcę, aby moja aplikacja podejmowała jakiekolwiek działania. Chcę tylko, aby działało bez pośredniego czyszczenia, ponieważ użytkownik nie zamknął aplikacji. Myślę więc, że bardziej sensowne jest wykonywanie prac związanych z czyszczeniem tylko w applicationDidEnterBackground.

Byłbym wdzięczny za Twój wkład w najlepsze praktyki, które należy zastosować przy wyborze delegatów, którzy mają się wdrożyć w celu przebudzenia i pójścia spać, a także rozważenia takich wydarzeń, jak przerwanie przez SMS / połączenia.

Dzięki

Paweł
źródło

Odpowiedzi:

449

Podczas budzenia, tj. Ponownego uruchamiania aplikacji (przez trampolinę, przełączanie aplikacji lub URL), applicationWillEnterForeground:wywoływana jest funkcja . Jest wykonywany tylko raz, gdy aplikacja jest gotowa do użycia, po umieszczeniu w tle, a applicationDidBecomeActive:może być wywoływany wiele razy po uruchomieniu. Jest to applicationWillEnterForeground:idealne rozwiązanie do konfiguracji, która musi nastąpić tylko raz po ponownym uruchomieniu.

applicationWillEnterForeground: jest nazywany:

  • po ponownym uruchomieniu aplikacji
  • przed applicationDidBecomeActive:

applicationDidBecomeActive: jest nazywany:

  • po pierwszym uruchomieniu aplikacji application:didFinishLaunchingWithOptions:
  • po, applicationWillEnterForeground:jeśli nie ma adresu URL do obsługi.
  • po application:handleOpenURL:jest nazywany.
  • po, applicationWillResignActive:jeśli użytkownik ignoruje zakłócenia, takie jak połączenie telefoniczne lub SMS.

applicationWillResignActive: jest nazywany:

  • gdy występuje przerwa, taka jak rozmowa telefoniczna.
    • jeśli użytkownik odbiera połączenie applicationDidEnterBackground:jest wywoływane.
    • jeśli użytkownik zignoruje połączenie applicationDidBecomeActive:zostanie wywołane.
  • po naciśnięciu przycisku Home lub zmianie aplikacji przez użytkownika.
  • doktorzy mówią, że powinieneś
    • wstrzymaj bieżące zadania
    • wyłącz zegary
    • wstrzymaj grę
    • zmniejsz liczbę klatek na sekundę OpenGL

applicationDidEnterBackground: jest nazywany:

  • po applicationWillResignActive:
  • Dokumenty mówią, że powinieneś:
    • zwolnić udostępnione zasoby
    • zapisz dane użytkownika
    • unieważnić liczniki
    • zapisz stan aplikacji, aby móc ją przywrócić, jeśli aplikacja zostanie zakończona.
    • wyłącz aktualizacje interfejsu użytkownika
  • masz 5 sekund na zrobienie tego, czego potrzebujesz i zwrot metody
    • jeśli nie wrócisz w ciągu ~ 5 sekund, aplikacja zostanie zakończona.
    • możesz poprosić o więcej czasu beginBackgroundTaskWithExpirationHandler:

Oficjalna dokumentacja.

Dan Sandland
źródło
10
Jeszcze jedna rzecz do dodania. Jeśli otworzysz listę aplikacji w tle ze swojej aplikacji (kliknij dwukrotnie przycisk Home), a następnie wrócisz do niej (wybierz podgląd aplikacji) - -applicationWillEnterForeground:nie zostanie wywołany, tylko -applicationDidEnterBackground:(załóżmy, że iOS nie uważa, że ​​jest to ponowne uruchomienie).
kpower
@kpower tak, że właśnie złamał mi kark ... nigdy nie pomyślałbym, że w tym przypadku nie zostanie nazwany
IntereForeground
Czy to nie applicationWillEnterForeground:będzie wywoływane za każdym razem od tła do pierwszego planu ?! Nie mogę znaleźć sprawy, która NIE zostanie nazwana BEZ applicationDidBecomeActivepóźniej.
Desmond DAI
To nie jest dokładne. applicationWillResignActive można wywoływać bez applicationDidEnterBackground
MichaelGofron
27

Zarządzanie cyklem życia aplikacji jest pomocne w przypadku pytań. Aby uzyskać szybką koncepcję, możesz zobaczyć Ryciny w tym dokumencie. Możesz także przeczytać komentarz z kodu wygenerowanego przez Kreatora XCode. Wymienione w następujący sposób:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. 
     This can occur for certain types of temporary interruptions (such as an 
     incoming phone call or SMS message) or when the user quits the application 
     and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down 
     OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate 
     timers, and store enough application state information to restore your 
     application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called 
     instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the active state; 
     here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the 
     application was inactive. If the application was previously in the 
     background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

Bardziej szczegółowe objaśnienia znajdują się w oficjalnym dokumencie dotyczącym UIApplicationDelegate

tomjpsun
źródło
Link jest martwy.
Phlippie Bosman
Sprawdź niektóre opisy i linki, na razie 2019.
tomjpsun
13

Nadal byłem trochę zdezorientowany odpowiedzią Dano, więc zrobiłem mały test, aby uzyskać przepływ zdarzeń w niektórych scenariuszach w celach informacyjnych, ale może być również przydatny dla ciebie. Dotyczy to aplikacji, których NIE używają UIApplicationExitsOnSuspendw swojej info.plist. Przeprowadzono to na symulatorze iOS 8 + potwierdzonym na urządzeniu z systemem iOS 7. Proszę wybaczyć nazwy modułu obsługi zdarzeń Xamarin. Są bardzo podobne.

  • Początkowe i wszystkie kolejne uruchomienia ze stanu nie uruchomionego:

Zakończone Uruchomienie

OnActivated

  • Przerwanie (połączenie telefoniczne, zsuwanie z góry, zsuwanie z dołu):
  • Przycisk strony głównej naciśnij dwukrotnie listę nieaktywnych aplikacji, a następnie ponownie wybierz naszą aplikację:

OnResignActivation


OnActivated

  • Przycisk strony głównej naciśnij dwukrotnie listę nieaktywnych aplikacji, wybierz inną aplikację, a następnie ponownie uruchom naszą aplikację:
  • Przycisk Home jednokrotnie naciśnij, a następnie uruchom ponownie:
  • Zablokuj (przycisk wł. / Wył.), A następnie odblokuj:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

  • Dwukrotnie naciśnij przycisk strony głównej i zakończ naszą aplikację: (pierwsze ponowne uruchomienie to pierwszy przypadek)

OnResignActivation

DidEnterBackground

DidEnterBackground (tylko iOS 7?)

Tak, DidEnterBackgroundjest wywoływany dwukrotnie na urządzeniu z systemem iOS7. Za każdym razem stanem UIApplication jest Tło. Jednak symulator iOS 8 tego nie robi. To wymaga przetestowania na urządzeniu z systemem iOS 8. Zaktualizuję swoją odpowiedź, kiedy ją złapię, lub ktoś inny może potwierdzić.

Rahmi Aksu
źródło
9

applicationWillEnterForeground jest nazywany:

przy ponownym uruchomieniu aplikacji (przechodzi z tła na pierwszy plan) Ta metoda nie jest wywoływana, gdy aplikacja uruchamia się po raz pierwszy, tj. kiedy applicationDidFinishLaunchjest wywoływana, ale tylko gdy pochodzi z tła applicationDidBecomeActive

applicationDidBecomeActive jest nazywany

po pierwszym uruchomieniu aplikacji didFinishLaunching po, applicationWillEnterForegroundjeśli nie ma adresu URL do obsługi. po application:handleOpenURL:jest nazywany. po, applicationWillResignActivejeśli użytkownik ignoruje zakłócenia, takie jak połączenie telefoniczne lub SMS. po zniknięciu alertView w dowolnym miejscu z aplikacji

Kareem Waheed
źródło
Czy przypadkiem wiesz, czy to się zmieniło od iOS 7? Pamiętam (mogłem się pomylić) robienie rzeczy (iOS 5/6) w applicationWillEnterForeground i uruchamianie ich przy pierwszym uruchomieniu aplikacji. Na razie w wersji 7.1 / 8 masz rację applicationWillEnterForeground nie jest wywoływany przy uruchomieniu.
Jinyoung Kim,
7

applicationWillResignActive jest wywoływany, gdy system prosi o uprawnienia. (w iOS 10). Na wypadek, gdyby ktoś wpadł w takie same kłopoty jak ja ...

Anson Yao
źródło
jakiś pomysł, jaka metoda zostanie wywołana po odrzuceniu zezwolenia pop? Mam ten problem stackoverflow.com/questions/26059927/...
Suresh Durishetti
5

W iOS 8+ istnieje subtelna, ale ważna różnica w podejmowaniu połączeń telefonicznych.

W systemie iOS 7, jeśli użytkownik odbierze telefon, wywoływane są zarówno applicationWillResignActive: jak i applicationDidEnterBackground: Ale w iOS 8+ wywoływana jest tylko aplikacja WillResignActive:

Qiulang
źródło
1

W systemie iOS 13+ zostaną wykonane następujące metody:

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene
użytkownik2994130
źródło