2010-09-14 6 views
174

¿Cuál es el delegado apropiado para implementar cuando una aplicación está despertando de estar en segundo plano y desea que esté preparada para ser activa?applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

applicationWillEnterForeground vs applicationDidBecomeActive - ¿Cuál es la diferencia?

¿Cuál es el delegado apropiado para implementar cuando una aplicación se va a suspender y desea prepararla para limpiar y guardar datos?

applicationWillResignActive vs. applicationDidEnterBackground - ¿Cuál es la diferencia?

Además, me he dado cuenta de que se llama a applicationWillResignActive cuando entra un SMS o una llamada pero el usuario elige hacer clic en Aceptar y continuar. No quiero que mi aplicación tome ninguna medida en estos casos. Solo quiero que siga funcionando sin ninguna limpieza intermedia ya que el usuario no salió de la aplicación. Entonces, creo que tiene más sentido hacer el trabajo de limpieza solo en applicationDidEnterBackground.

Agradecería su opinión sobre las mejores prácticas para seguir eligiendo qué delegados implementar para despertarse y dormir, así como considerar eventos como ser interrumpido por SMS/llamadas.

Gracias

Respuesta

18

This Apple Document es útil a sus preguntas. Para un concepto rápido, puede ver la Figura 3-1 en ese documento. También puede leer el comentario del código generado por el Asistente de XCode. Listado de la siguiente manera:

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

En el código anterior, sólo la aplicación lanzamiento usted tiene la oportunidad de decir sí o no, los demás son sólo las notificaciones. En otras palabras, no tiene forma de obligar a los usuarios a descuidar la llamada entrante o los SMS mediante el listado de códigos anterior. No sé si hay alguna otra solución.

362

Al despertar, es decir, relanzar una aplicación (ya sea a través de un trampolín, cambio de aplicación o URL) applicationWillEnterForeground: se llama. Solo se ejecuta una vez cuando la aplicación está lista para su uso, después de ponerla en segundo plano, mientras que applicationDidBecomeActive: se puede llamar varias veces después del inicio. Esto hace que applicationWillEnterForeground: sea ideal para la configuración que debe ocurrir solo una vez después del relanzamiento.

applicationWillEnterForeground: se llama:

  • cuando se relanza aplicación
  • antes applicationDidBecomeActive:

applicationDidBecomeActive: se llama:

  • cuando la aplicación se pone en marcha por primera vez después application:didFinishLaunchingWithOptions:
  • después applicationWillEnterForeground: si no hay URL de manejar.
  • después de application:handleOpenURL: se llama.
  • después de applicationWillResignActive: si el usuario ignora la interrupción como una llamada telefónica o un SMS.

applicationWillResignActive: se llama:

  • cuando hay una interrupción como una llamada telefónica.
    • si el usuario toma la llamada applicationDidEnterBackground: se llama.
    • si el usuario ignora la llamada applicationDidBecomeActive: se llama.
  • cuando se presiona el botón de inicio o el usuario cambia de aplicación.
  • documentos dicen que debe
    • pausa tareas en curso
    • temporizadores desactivar
    • pausa un juego
    • reducir las velocidades de cuadro OpenGL

applicationDidEnterBackground: se llama:

  • después applicationWillResignActive:
  • docs decir que debiera: recursos compartidos
    • liberación
    • Guardar datos de usuario
    • temporizadores Invalidate
    • guardar el estado de aplicación para que pueda restaurarlo en caso de aplicación es terminado.
    • actualizaciones de la interfaz de usuario desactivar
  • que tienen 5 segundos para hacer lo que necesita y volver al método
    • si no vuelve dentro de ~ 5 segundos se termina la aplicación.
    • se puede pedir más tiempo con beginBackgroundTaskWithExpirationHandler:

The official documentation.

+0

lo que describes es lo que especifica la respuesta. la pregunta pregunta cómo manejar una aplicación que está despertando de estar en el fondo (es decir, relanzamiento), no se está iniciando. –

+0

¡Ups! Estaba malinterpretando la terminología que estaba usando (reinicio vs lanzamiento) – Dima

+9

Una cosa más para agregar. Si abre una lista de aplicaciones en segundo plano desde su aplicación (haga doble clic en el botón de inicio) y luego regrese a ella (elija la vista previa de su aplicación) - '-applicationWillEnterForeground:' no se llamará, solo '-applicationDidEnterBackground:' (suponga, iOS no pienses que es un relanzamiento). – kpower

12

todavía estaba un poco confundido con la respuesta de Dano así que hice una pequeña prueba para obtener el flujo de los acontecimientos en ciertos escenarios para mi referencia, pero también podría serle útil. Esto es para aplicaciones que NO usan UIApplicationExitsOnSuspend en su info.plist. Esto se realizó en un simulador de iOS 8 + confirmado con el dispositivo iOS 7. Disculpe los nombres del manejador de eventos de Xamarin. Ellos son muy similares.

  • inicial y todos los lanzamientos posteriores desde un estado no-funcionamiento:

FinishedLaunching

OnActivated

  • interrupción (llamada telefónica, carro superior hacia abajo, deslizadera inferior):
  • botón de Inicio pulse dos veces la lista de aplicaciones inactivas, a continuación, volver a seleccionar nuestra aplicación:

OnResignActivation


OnActivated

  • botón de Inicio pulse dos veces la lista de aplicaciones inactivas, seleccionando otra aplicación, luego relanzar nuestra aplicación:
  • botón de inicio de prensa única, a continuación, relanzar:
  • bloqueo (encendido/apagado), a continuación, desbloquear:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

    botón
  • Inicio doble prensa, y terminar nuestra aplicación: (relanzamiento posterior es el primer caso)

OnResignActivation

DidEnterBackground

DidEnterBackground (iOS 7 sólo?)

Sí, DidEnterBackground se llama dos veces en el dispositivo iOS7. En ambas ocasiones, el estado de la aplicación UIA es en segundo plano. Sin embargo, el simulador iOS 8 no. Esto necesita pruebas en el dispositivo iOS 8. Actualizaré mi respuesta cuando lo tenga en mis manos, o alguien más pueda confirmarlo.

8

applicationWillEnterForeground se llama:

cuando se relanza aplicación (viene de fondo a primer plano) Este método no se invoca cuando la aplicación se inicia por primera vez.e cuando applicationDidFinishLaunch se llama pero sólo cuando proviene de fondo applicationDidBecomeActive

applicationDidBecomeActive se llama

cuando la aplicación se inicia por primera vez después didFinishLaunching después applicationWillEnterForeground si no hay URL de manejar. Se llama después de application:handleOpenURL:. después de applicationWillResignActive si el usuario ignora la interrupción como una llamada telefónica o un SMS. después de desaparecer de alertView en cualquier lugar de la aplicación

+0

¿Sabe por casualidad si esto cambió a partir de iOS 7? Recuerdo (podría estar equivocado) haciendo cosas (iOS 5/6) en applicationWillEnterForeground y ejecutándome cuando la aplicación se lanzó por primera vez. A partir de ahora, en 7.1/8, tiene razón en la aplicaciónWillEnterForeground no se llama al iniciarse. –

4

En iOS 8+ hay una diferencia sutil pero importante para tomar una llamada telefónica.

En iOS 7 si el usuario toma una llamada telefónica, se llama a ambas applicationWillResignActive: y applicationDidEnterBackground. Pero en iOS 8+ solo se llama a applicationWillResignActive:

3

applicationWillResignActive se invoca cuando el sistema solicita permisos. (en iOS 10). En caso de que alguien se meta en el mismo problema que yo ...

+0

¿Alguna idea de qué método se llama después de cerrar el permiso pop? Tengo este problema https://stackoverflow.com/questions/26059927/applicationdidbecomeactive-not-called-when-launching-app-from-banner-custom-acti –

Cuestiones relacionadas