Suppose I have an iOS app that is actually running in the background (for one of several legal reasons, such as background audio, requested time, etc.). What things might cause the OS to close (kill) this app instead of just running or suspending it? How can I avoid them? How can I reliably trigger them (within this app) using public APIs?
Your app might be killed if it uses too much memory, if it does not call endBackgroundTask: when the expiration handler (specified when calling beginBackgroundTaskWithExpirationHandler:) is called, if the user explicitly kills it, if the app throws an exception, calls exit, triggers an EXC_BAD_ACCESS or other signal, and so on. There are probably other reasons, too.
To avoid these, don't use too much memory, call endBackgroundTask: when required, make an app that users won't want to kill, and don't throw exceptions, call exit, access invalid memory locations, and so on.
There isn't a way to reliably trigger "user explicitly kills the app". For the others, you could allocate tons of memory, refuse to call endBackgroundTask:, use [NSException raise:... format:...], call exit, or create random garbage pointers and follow them. You probably shouldn't actually do any of these, though.
I'm not sure what you're asking - it sounds like you want to be able to terminate other applications, which (thankfully) simply isn't possible on the iOS platform due to sandboxing, etc.
However, the most likely reason your own application will be killed whilst it's running in the background is if it's using a large amount of memory, etc. and doesn't respond to the didReceiveMemoryWarning calls by shedding resources that are no longer required.
In terms of automatically triggering these, the simplest way would be to use the "Simulate memory warning" option within the "Hardware" menu on the simulator.
Related
Is it advisable or any issues with calling both startUpdatingLocation and startMonitoringSignificantChanges vs. one or the other? I understand the benefits of the significant changes call re: battery life, but when using it am seeing inconsistency with it firing the didUpdateToLocation, sometimes doesn't fire at all even though I know I've setup locations where I know it should fire when I'm at the location but doesn't. I'm able to verify my results for my app vs. another app that does very similar behavior, including both mine and the other app running in the background (UIBackgroundModes does have the 'App registers for location updates' setting in the plist). If I try using just the significant changes, the results are not consistent. If I use both, I get accurate results + the added benefit (need) for getting notified if/when the app is terminated. I want to not kill the battery life by using the startUpdatingLocation, and have tried calling the stopUpdatingLocation and then subsequently calling the startMonitoringSignificantChanges in the applicationDidEnterBackground in order to help conserve battery life while in the background, but can't seem to understand why relying on the significant changes is not working consistently.
Apple suggests that you use -startUpdatingLocation while your app is in the foreground, and -startMonitoringSignificantChanges while in the background. Using both while the app is in the foreground is likely just a waste and more likely to be more work to handle the events than just monitoring -didUpdateToLocation. Upon backgrounding, you can switch off the GPS mode and switch to something more low powered. You have to assume that the user won't care as much for accuracy once you've been backgrounded or closed.
I am making an app, which needs to keep tracking user's location every time. It can also work in the background mode. The issue is When I use other apps for several times. The other app may cause lots of memory. My app sometimes be terminated by the system. There are no crash logs. So I want to know some reasons. Is there any way to avoid my app to be terminated? Very appreciate for your help.
You can't prevent the app the be terminated, but what can you do best to keep it alive is when it enters in background free as much memory as you can - cached images, files... Also stop any running timers, UI updates and everything time consuming. By following the MVC rules, the best implementation is to create a separate class (model) that's only responsible for location updates (with CLLocationManager inside, and the class implements its delegation methods). So the only thing in background you should do is collecting the location points received by the CLLocationManager and nothing else. Also implement the method -applicationWillTerminate in you AppDelegate. This method is called only when the app is in background and it's going to be terminated (either by the OS or the user) and inside persist the location points in CoreData for example or however you do it... I have such an approach and so far my app has lived for 24h (with charging of course) without being killed.
App running in the background depend upon memory usage, battery life etc.When there are many app running in the background, your app may get terminated.I do not think you can run your app permanently in background.
While the device is powered on, is it possible for iOS to automatically terminate my app (calling applicationWillTerminate:) while it's in the background?
I'm also curious what happens in two other cases, three in total:
Device is powered on
Device is powered off
Device loses battery
I'm asking because I want to know how often applicationWillTerminate: is likely to get called. I want to know this because that's where I'm registering for remote notifications. And if there's a failure sending the device token to the server, I want to know how likely it is that that method will get called again (i.e., retry sending the device token to the server).
If your application supports multitasking (the default for anything linked against iOS 4.0+), this method will almost never be called. The documentation says it may be called in cases where the application is running in the background and the system wants to terminate. However, in my experience, I've only ever seen this actually called when running a music app that's actively playing music in the background and the system is jettisoning everything. In cases where I have background tasks running (not music, but short-term background tasks), I've seen the app terminated without this method being called.
I wouldn't ever rely on this being called and try and do all the clean-up you need to do in your delegate methods for transitioning into the background and your background task completion blocks (which do get executed for at least a few seconds before the app gets jettisoned).
Not only can iOS terminate your app automatically, but the user can kill it manually. In fact, the only time the user can kill your app is when it's in the background. Furthermore, when your app is "in the background" it's more likely to be suspended than actually running, so don't count on doing a lot of processing when you're not the foreground app.
As for how likely it is that you'll get -applicationWillTerminate:, that'll depend on the user and how they're using their device. You should handle it appropriately when you get it, and go about your business otherwise.
When memory is running low, iOS can shut down your app, calling applicationWillTerminate.
The docs say this about the method:
... However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.
Check out iOS Developer Library : iOS App Programming Guide : App Termination.
I have made an app that runs in the background. The purpose is to intercept incoming calls. After a while Android kills the service/app if it's not "active" for a while. Any way to avoid this in basic4android?
Set the service to be a foreground service.
Run Service.StartForeground from the service module
When you are finished processing use:Service.StopForeground to stop the service from being a foreground service.
The easiest way to avoid this problem is to place a notification icon in the top bar. Android will not kill processes that have a notification icon unless the phone is running very short on memory.
However, you may want to make this icon an option to the user (default: on), because higher end phones won't kill processes unless they have a memory shortage anyway.
Unfortunately, I don't know how to implement this.
[edit]
You could also make the app do something completely pointless every 15 minutes, like set a useless variable. This would classify the application as active to the system. You'd still have to worry about low memory situations, though.
I'm setting "Application does not run in background" to NO
which means, it can go background and resumed later.
I'm putting some code in "applicationDidEnterBackground",
and I would like to force quit the app when desirable. (when there's nothing to do in background.)
I read 'exit' is not recommended.
Can I post a message which will result in something like applicationWillTerminate maybe?
Edit
Let me clarify why I would want that,
I want my app to run background when it's downloading something.. via beginBackgroundTaskWithExpirationHandler
But if user isn't downloading anything, I can safely quit the application.
Thank you
The general Apple approach on iOS is that applications should never terminate themselves, for any reason.
It's important to understand that when your application is 'running' in the background, it's not really running: the 'Application does not run in background' key is basically there to ensure backwards compatibility with applications built for iOS 3 and lower, which tend to make certain assumptions about how the user will enter the app. There are very few reasons why a new app wouldn't support it.
Basically, don't bother: I suppose you could technically call exit(), but Apple will hate you for it, and it's bad style for the platform.
You don't need to worry about this.
If you have work to do in the background and you set up a background task then it'll run for as long as it needs and execute its handler when done.
What you don't seem to be aware of is that if you have nothing to do in the background, your app is simply suspended and in fact does not run.
As this is the case, there's nothing you need to do, quitting the app won't gain you anything that you don't already get with suspension.