applicationWillEnterForeground против applicationDidBecomeActive, applicationWillResignActive против applicationDidEnterBackground - PullRequest
199 голосов
/ 15 сентября 2010

Какой правильный делегат следует реализовать, когда приложение просыпается из фонового режима и вы хотите, чтобы оно подготовило его к активному действию?

applicationWillEnterForeground vs applicationDidBecomeActive - В чем разница?

Какой правильный делегат для реализации, когда приложение собирается в спящий режим, и вы хотите подготовить его к очистке и сохранению данных?

applicationWillResignActive против applicationDidEnterBackground - Какая разница?

Кроме того, я заметил, что applicationWillResignActive вызывается при входящем SMS или входящем звонке, но пользователь решает нажать Ok и продолжить.Я не хочу, чтобы мое приложение предпринимало какие-либо действия в этих случаях.Я просто хочу, чтобы он продолжал работать без какой-либо промежуточной очистки, поскольку пользователь не выходил из приложения.Итак, я думаю, что имеет больше смысла выполнять работу по очистке только в applicationDidEnterBackground.

Буду признателен за ваш вклад в рекомендации по выбору тех делегатов, которые нужно реализовать для пробуждения и сна, а также для рассмотрениятакие события, как прерывание с помощью SMS / звонков.

Спасибо

Ответы [ 6 ]

417 голосов
/ 25 марта 2012

При пробуждении, т.е. перезапуске приложения (через трамплин, переключение приложений или URL), вызывается applicationWillEnterForeground:.Он выполняется только один раз, когда приложение становится готовым к использованию, после помещения в фоновый режим, тогда как applicationDidBecomeActive: может вызываться несколько раз после запуска.Это делает applicationWillEnterForeground: идеальным для настройки, которая должна произойти только один раз после перезапуска.

applicationWillEnterForeground: называется:

  • когда приложение перезапускается
  • до applicationDidBecomeActive:

applicationDidBecomeActive: вызывается:

  • когда приложение запускается впервые после application:didFinishLaunchingWithOptions:
  • после applicationWillEnterForeground:, если нет URL для обработки.
  • после вызова application:handleOpenURL:.
  • после applicationWillResignActive: если пользователь игнорирует прерывание, например, телефонный звонок или SMS.

applicationWillResignActive: вызывается:

  • когда есть прерывание как телефонный звонок.
    • если пользователь принимает вызов applicationDidEnterBackground:.
    • , если пользователь игнорирует вызов applicationDidBecomeActive:.
  • когда нажата кнопка «Домой» или пользователь переключает приложения.
  • документы говорят, что вы должны
    • приостановить текущие задачи
    • отключить таймеры
    • приостановить игру
    • уменьшить частоту кадров OpenGL

applicationDidEnterBackground: называется:

  • послеapplicationWillResignActive:
  • документы говорят, что вы должны:
    • освободить общие ресурсы
    • сохранить данные пользователя
    • аннулировать таймеры
    • сохранить состояние приложения, чтобы вы могли восстановить его, если приложение завершено.
    • отключить обновления пользовательского интерфейса
  • у вас есть 5 секунд, чтобы сделать то, что вам нужно, и вернуть метод
    • если вы не вернетесь в течение ~ 5 секунд, приложение будет остановлено.
    • вы можете запросить больше времени с помощью beginBackgroundTaskWithExpirationHandler:

Официальная документация.

26 голосов
/ 10 ноября 2011

Этот документ Apple полезен для ваших вопросов.Для быстрого понимания вы можете увидеть рисунок 2-3 в этом документе.Вы также можете прочитать комментарий из кода, сгенерированного мастером XCode.Перечислено следующим образом:

- (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:.
     */
}

В приведенном выше коде только приложение , запускающее , имеет ли вы возможность сказать ДА или НЕТ, другие - просто уведомления.Другими словами, вы не можете заставить пользователей пренебречь входящим звонком или SMS-сообщением с помощью кода, приведенного выше.Не знаю, есть ли другой обходной путь.

13 голосов
/ 23 сентября 2014

Я все еще был немного смущен ответом Дано, поэтому я провел небольшой тест, чтобы получить поток событий в определенных сценариях для справки, но он может быть полезен и вам.Это для приложений, которые НЕ используют UIApplicationExitsOnSuspend в своем info.plist.Это было проведено на симуляторе iOS 8 + подтверждено на устройстве iOS 7.Пожалуйста, извините имена обработчиков событий Xamarin.Они очень похожи.

  • Первоначальный и все последующие запуски из неработающего состояния:

FinishedLaunching

OnActivation

  • Прерывание (телефонный звонок, верхний слайд, нижний слайд вверх):
  • Кнопка «Домой» дважды нажимает на список неактивных приложений, а затем повторно выбирает наше приложение:

OnResignActivation


OnActivation

  • Кнопка «Домой» дважды нажимает на список неактивных приложений, выбирает другое приложение и затем перезапускает наше приложение:
  • Однократное нажатие кнопки «Домой», затем повторный запуск:
  • Блокировка (кнопка включения / выключения), затем разблокировка:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivation

  • Дважды нажмите кнопку «Домой» и закройте наше приложение: (последующий перезапуск - первый случай)

OnResignActivation

DidEnterBackground

DidEnterBackground(только для iOS 7?)

Да, DidEnterBackground вызывается дважды на устройстве iOS7.Оба раза UIApplication состояние является фоновым.Однако симулятор iOS 8 этого не делает.Это требует тестирования на устройстве iOS 8.Я обновлю свой ответ, когда получу руку, или кто-то другой может подтвердить.

9 голосов
/ 04 ноября 2014

applicationWillEnterForeground называется:

при перезапуске приложения (из фона на передний план) Этот метод не вызывается, когда приложение запускается в первый раз, т.е. когда вызывается applicationDidFinishLaunch, но только когда оно происходит из фона applicationDidBecomeActive

applicationDidBecomeActive называется

при первом запуске приложения после didFinishLaunching после applicationWillEnterForeground, если нет URL для обработки. после вызова application:handleOpenURL:. после applicationWillResignActive, если пользователь игнорирует прерывание, например, телефонный звонок или SMS. после исчезновения alertView в любом месте из приложения

7 голосов
/ 03 декабря 2016

applicationWillResignActive вызывается, когда система запрашивает разрешения. (в iOS 10). На всякий случай, если кто-нибудь попадет в ту же проблему, что и я ...

5 голосов
/ 30 января 2015

В iOS 8+ есть небольшая, но важная разница для приема телефонных звонков.

В iOS 7, если пользователь принимает телефонные звонки, вызываются и applicationWillResignActive: и applicationDidEnterBackground:Но в iOS 8+ называется только приложение WillResignActive:

...