applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

215

Qual é o delegado adequado a ser implementado quando um aplicativo está sendo ativado em segundo plano e você deseja prepará-lo para ser ativo?

applicationWillEnterForeground vs applicationDidBecomeActive - Qual é a diferença?

Qual é o delegado adequado a ser implementado para quando um aplicativo entra em suspensão e você deseja prepará-lo para limpar e salvar dados?

applicationWillResignActive vs. applicationDidEnterBackground - Qual é a diferença?

Além disso, notei que applicationWillResignActive é chamado quando um SMS ou chamada é recebida, mas o usuário escolhe clicar em OK e continuar. Não quero que meu aplicativo execute nenhuma ação nesses casos. Eu só quero que ele continue funcionando sem nenhuma limpeza intermediária, pois o usuário não saiu do aplicativo. Portanto, acho que faz mais sentido fazer o trabalho de limpeza apenas no applicationDidEnterBackground.

Agradeço sua opinião sobre as práticas recomendadas a seguir na escolha de quais delegados implementar para acordar e dormir, além de considerar eventos como ser interrompido por SMS / chamadas.

obrigado

Paulo
fonte

Respostas:

449

Ao acordar, ou seja, é reiniciado um aplicativo (através de trampolim, alternância de aplicativo ou URL) applicationWillEnterForeground:. Ele é executado apenas uma vez quando o aplicativo fica pronto para uso, depois de ser colocado em segundo plano, enquanto applicationDidBecomeActive:pode ser chamado várias vezes após o lançamento. Isso é applicationWillEnterForeground:ideal para configurações que precisam ocorrer apenas uma vez após o reinício.

applicationWillEnterForeground: é chamado:

  • quando o aplicativo é reiniciado
  • antes applicationDidBecomeActive:

applicationDidBecomeActive: é chamado:

  • quando o aplicativo é iniciado pela primeira vez após application:didFinishLaunchingWithOptions:
  • depois, applicationWillEnterForeground:se não houver URL para manipular.
  • depois application:handleOpenURL:é chamado.
  • after applicationWillResignActive:if o usuário ignora a interrupção como uma ligação ou SMS.

applicationWillResignActive: é chamado:

  • quando houver uma interrupção como uma ligação telefônica.
    • se o usuário atender applicationDidEnterBackground:é chamado.
    • se o usuário ignorar a chamada applicationDidBecomeActive:é chamada.
  • quando o botão home é pressionado ou o usuário alterna entre aplicativos.
  • os médicos dizem que você deveria
    • pausar tarefas em andamento
    • desativar temporizadores
    • pausar um jogo
    • reduzir taxas de quadros OpenGL

applicationDidEnterBackground: é chamado:

  • depois de applicationWillResignActive:
  • Os médicos dizem que você deve:
    • liberar recursos compartilhados
    • salvar dados do usuário
    • invalidar temporizadores
    • salve o estado do aplicativo para restaurá-lo se o aplicativo for encerrado.
    • desativar atualizações da interface do usuário
  • você tem 5 segundos para fazer o que precisa e retornar o método
    • se você não retornar dentro de ~ 5 segundos, o aplicativo será encerrado.
    • você pode pedir mais tempo com beginBackgroundTaskWithExpirationHandler:

A documentação oficial.

Dan Sandland
fonte
10
Mais uma coisa para adicionar. Se você abrir a lista de aplicativos em segundo plano a partir do seu aplicativo (clique duas vezes no botão home) e retornar a ele (escolha a visualização do aplicativo) - -applicationWillEnterForeground:não será chamado apenas -applicationDidEnterBackground:(suponha que o iOS não pense que é um relançamento).
precisa saber é
@kpower sim, que apenas quebrou meu pescoço ... nunca teria pensado que willEnterForeground não será chamado nesse caso ...
theeye
Não é isso que applicationWillEnterForeground:será chamado sempre de segundo plano para primeiro plano ?! Não consigo encontrar um caso que NÃO seja chamado SEM applicationDidBecomeActiveposteriormente.
Desmond DAI
Isso não é exato. applicationWillResignActive pode ser chamado sem applicationDidEnterBackground
MichaelGofron
27

Gerenciar o ciclo de vida do seu aplicativo é útil para suas perguntas. Para um conceito rápido, você pode ver figuras nesse documento. Você também pode ler o comentário do código gerado pelo Assistente de XCode. Listados da seguinte forma:

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

Para explicações mais detalhadas, consulte o documento oficial do UIApplicationDelegate

tomjpsun
fonte
O link está morto.
Phlippie Bosman 16/05/19
Revise algumas descrições e links, 2019 por enquanto.
tomjpsun
13

Eu ainda estava um pouco confuso com a resposta de Dano, então fiz um pequeno teste para obter o fluxo de eventos em certos cenários para minha referência, mas pode ser útil para você também. Isso é para aplicativos que NÃO usam UIApplicationExitsOnSuspendem seu info.plist. Isso foi realizado em um simulador do iOS 8 + confirmado com o dispositivo iOS 7. Desculpe os nomes dos manipuladores de eventos do Xamarin. Eles são muito parecidos.

  • Inicia e todos os lançamentos subsequentes de um estado não em execução:

FinalizadoLançamento

OnActivated

  • Interrupção (telefonema, deslize superior para baixo, inferior):
  • Botão Página inicial, pressione duas vezes a lista de aplicativos inativos e selecione novamente nosso aplicativo:

OnResignActivation


OnActivated

  • Pressione o botão Página inicial pressionando duas vezes a lista de aplicativos inativos, selecionando outro aplicativo e reiniciando o aplicativo:
  • Pressione o botão Início uma vez e reinicie:
  • Bloqueie (botão liga / desliga) e desbloqueie:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

  • O botão Página inicial pressiona duas vezes e encerra nosso aplicativo: (o relançamento subsequente é o primeiro caso)

OnResignActivation

DidEnterBackground

DidEnterBackground (apenas iOS 7?)

Sim, DidEnterBackgroundé chamado duas vezes no dispositivo iOS7. Nas duas vezes, o estado UIApplication é Background. No entanto, o simulador do iOS 8 não. Isso precisa ser testado no dispositivo iOS 8. Atualizo minha resposta quando coloco minha mão nela, ou alguém pode confirmar.

Rahmi Aksu
fonte
9

applicationWillEnterForeground é chamado:

quando o aplicativo é reiniciado (vem do plano de fundo para o primeiro plano) Esse método não é chamado quando o aplicativo é iniciado pela primeira vez, ou seja, quando applicationDidFinishLaunché chamado, mas somente quando vem do plano de fundo applicationDidBecomeActive

applicationDidBecomeActive é chamado

quando o aplicativo for iniciado pela primeira vez depois didFinishLaunching depois, applicationWillEnterForegroundse não houver URL para manipular. depois application:handleOpenURL:é chamado. after applicationWillResignActiveif o usuário ignora a interrupção como uma ligação ou SMS. depois de desaparecer do alertView em qualquer lugar do aplicativo

Kareem Waheed
fonte
Você por acaso sabe se isso foi alterado no iOS 7? Lembro-me (posso estar enganado) de fazer coisas (iOS 5/6) no applicationWillEnterForeground e de executá-lo quando o aplicativo foi iniciado. A partir de agora, no 7.1 / 8, você está certo applicationWillEnterForeground não é chamado no lançamento.
Jinyoung Kim
7

applicationWillResignActive é chamado quando o sistema está solicitando permissões. (no iOS 10). Apenas no caso de alguém ter o mesmo problema que eu ...

Anson Yao
fonte
alguma idéia de qual método é chamado após a permissão pop demitir? Eu tenho esse problema stackoverflow.com/questions/26059927/…
Suresh Durishetti
5

No iOS 8 ou superior, há uma diferença sutil, mas importante, para atender chamadas.

No iOS 7, se o usuário atender a chamada, applicationWillResignActive: e applicationDidEnterBackground: serão chamados. Mas no iOS 8 ou superior, apenas applicationWillResignActive: é chamado.

Qiulang
fonte
1

Para iOS 13+, os seguintes métodos serão executados:

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene
user2994130
fonte