ApplicationWillEnterForeground против applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

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

applicationWillEnterForeground vs applicationDidBecomeActive - какая разница?

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

applicationWillResignActive vs. applicationDidEnterBackground - Какая разница?

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

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

Спасибо

Ответ 1

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

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

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

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

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

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

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

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

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

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

Ответ 2

Управление жизненным циклом приложения полезно для ваших вопросов. Для быстрого понимания вы можете увидеть цифры в этом документе. Вы также можете прочитать комментарий из кода, сгенерированного мастером 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:.
     */
}

Более подробные объяснения см. в официальном документе для UIApplicationDelegate.

Ответ 3

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

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

FinishedLaunching

OnActivated

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

OnResignActivation


OnActivated

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

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

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

OnResignActivation

DidEnterBackground

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

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

Ответ 4

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

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

applicationDidBecomeActive называется

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

Ответ 5

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

Ответ 6

В iOS 8+ есть тонкая, но важная разница для телефонного звонка.

В iOS 7, если пользователь делает телефонный звонок, вызываются как applicationWillResignActive: так и applicationDidEnterBackground:. Но в iOS 8+ вызывается только applicationWillResignActive: