applicationWillEnterForeground против applicationDidBecomeActive, applicationWillResignActive против applicationDidEnterBackground

215

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

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

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

applicationWillResignActive и applicationDidEnterBackground - в чем разница?

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

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

Спасибо

Павел
источник

Ответы:

449

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

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

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

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

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

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

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

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

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

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

Дэн Сэндленд
источник
10
Еще одна вещь, чтобы добавить. Если вы откроете фоновый список приложений из своего приложения (дважды щелкните кнопку «Домой»), а затем вернетесь к нему (выберите предварительный просмотр вашего приложения) - -applicationWillEnterForeground:не будет вызываться, только -applicationDidEnterBackground:(предположим, iOS не считает, что это перезапуск).
kpower
@kpower да, это просто сломало мне шею ... никогда бы не подумал, что willEnterForeground не будет вызываться в этом случае ...
TheEye
Разве это applicationWillEnterForeground:не будет вызываться каждый раз от фона к переднему плану ?! Я не могу найти случай, когда он НЕ будет назван БЕЗ applicationDidBecomeActiveвпоследствии.
Десмонд DAI
Это не точно. applicationWillResignActive может быть вызван без applicationDidEnterBackground
MichaelGofron
27

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

tomjpsun
источник
Ссылка мертва.
Флиппи Босман
Пересмотрите некоторые описания и ссылки, 2019 на данный момент.
Tomjpsun
13

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

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

FinishedLaunching

OnActivated

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

OnResignActivation


OnActivated

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

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

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

OnResignActivation

DidEnterBackground

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

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

Рахми Аксу
источник
9

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

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

applicationDidBecomeActive называется

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

Карим Вахид
источник
Вы случайно не знаете, было ли это изменено в iOS 7? Я помню (я могу ошибаться) делать вещи (iOS 5/6) в applicationWillEnterForeground и запускать их при первом запуске приложения. На данный момент, в версии 7.1 / 8, вы правы applicationWillEnterForeground не вызывается при запуске.
Jinyoung Ким
7

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

Ансон Яо
источник
Любая идея, какой метод вызывается после разрешения поп отклонить? У меня есть эта проблема stackoverflow.com/questions/26059927/…
Суреш Дуришетти
5

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

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

Qiulang
источник
1

Для iOS 13+ будут выполнены следующие методы:

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene
user2994130
источник