What happens if a user closes an application that is already in the background?

During the execution of the background task, what happens if the user kills the application (which is already in the background)?

Figure this out:

The application launches task X (with support for 10 minutes and an expiration handler that must be called). Then the application goes into the background and the user kills the application.

I am confused about what will happen to task X after the application is killed. Does this background time remain for execution? Is the expiration handler called?

+4
source share
3 answers

If the application is already in the background, the user has already "closed the application"! So what can your question mean? You have already faded into the background, and if you called beginBackgroundTaskWithExpirationHandler: as you did, everything will be fine.

Do you mean that the user forcibly kills the application in the background, calling the "latest applications" interface and switching to jiggy mode and removing the application from the "recent applications" interface? Then the application will be killed; you do not receive notifications, and everything that you do is interrupted.

In addition, the only thing the expiration handler should do is call endBackgroundTask: If you were killed, then the fact that you cannot complete this call is unimportant!

+3
source

Ok so this is the result

In this case, the OS will send a SIGKILL signal to your application process, and the applicationWillTerminate method will not be called.

Below is just my interpretation from Apple docs, work results and Google results.

In this case, the delegate method will receive a call below your application method

 - (void)applicationWillTerminate:(UIApplication *)application 

Quote from Apple Docs

For applications that do not support background execution or are associated with iOS 3.x or earlier, this method is always called when the user shuts down the application. For applications that support background execution, this method is usually not called when the user terminates the application, because the application simply moves to the background in this case. However, this method can be called in a situation where the application is running in the background (not paused), and the system must stop it for some reason.

So you must have the UIApplicationExitsOnSuspend value for YES in your plist file, otherwise there is no guarantee that applicationWillTerminate: will ever be called. This is why the document can be used.

I do not think that the expiration handler block will be called, although I'm not sure.

+1
source

This is pretty easy to verify, so I just did (on iPhone 4S running iOS 6.1.3) using the code that I paste at the end that runs the background job in the delegate method applicationDidEnterBackground . <ears>
The result is amazing. When a user exits the application by clicking the "Home" button, then manually kills the application (double-clicking "Home", moving things to jigging mode and clicking the close icon of the application), the following will happen:

  • applicationWillTerminate .
  • When applicationWillTerminate completes, background execution completes no matter how long the background task runs. The application was killed.

BUT..

If you arrange things so that applicationWillTerminate does not exit after the call, as in my code below, the following happens: at least in my test setup - when the application manually kills:

  • The background task of the application continues to run in the background .
  • Even when the execution time of the highlighted background has expired, the background task continues to run, like the code in applicationWillTerminate , until this method exits.

This is clearly a mistake - you cannot continue to execute the code forever - and I will not rely on the fact that it always works. But those who used various hacks around playing sound in the background to keep the application alive might want to explore. I would be interested if other people try the code on different versions / devices of iOS and get the same results.

Code for AppDelegate.m in my test project:

 // // BTAppDelegate.m // BackgroundTest // // Created by David Fearon on 07/05/2013. // Copyright (c) 2013 David Fearon. All rights reserved. // #import "BTAppDelegate.h" @implementation BTAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"application didFinishLaunchingWithOptions called"); // Override point for customization after application launch. return YES; } - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"applicationWillResignActive: called"); } - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"applicationDidEnterBackground: called"); UIApplication* thisApp = [UIApplication sharedApplication]; UIBackgroundTaskIdentifier __block task = [thisApp beginBackgroundTaskWithExpirationHandler:^{ }]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self printTimeRemaining]; while(YES) { [NSThread sleepForTimeInterval:1.0]; [self printTimeRemaining]; } //[thisApp endBackgroundTask:task]; }); } -(void)printTimeRemaining{ NSLog(@"Background task time remaining: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]); } - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"applicationWillEnterForeground: called"); } - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"applicationDidBecomeActive: called"); } - (void)applicationWillTerminate:(UIApplication *)application { NSLog(@"applicationWillTerminate: called"); while(YES) { [NSThread sleepForTimeInterval:1.0]; NSLog(@"Still executing code in applicationWillTerminate."); } } @end 
+1
source

All Articles