I am using a passcode lock on my app. I set a varibale to true/false in shared preferences using the logic in this answer. But this approach doesn't work when I kill the app while still on foreground (using recent apps). Looks like killing the app kills my TimerTask which is scheduled for 2secs and hence the variable never gets set.
I have tried using services to do the same but no luck, even services get killed when the app is killed. Any workaround for this? Please help!!
You can use Service with START_STICKY, which will be recreated after killing. Check AlarmManager for events that will be launched by system even if your app is closed.
I personally suggest using the AlarmManager, instead of keeping long-running services.
The best way to execute background tasks in an efficient way is to use an IntentService
http://developer.android.com/reference/android/app/IntentService.html
An IntentService is going to run in a separate thread as long as the task requires and will be killed afterwards.
Also it will enqueue requests and deal with the queue itself
Related
I'm trying to use ExecutorService for an Android project. I need it to be running for the duration of the application, and shutdown when the application shuts down. The problem is, on Android, detecting the shutdown of an application is a bit tricky. So what would happen if I never shutdown ExecutorService on an Android application?
What happens when I never call shutdown on ExecutorService?
you will waste some resources it keeps - how large those resources are depends on your executor. You can read in docs: "An unused executorService should be shut down to allow reclamation of its resources."
The problem is, on Android, detecting the shutdown of an application is a bit tricky
actually you should never shutdown your app process yourself, there are ways for doing this - but they are regarder as antipatterns. You normally "close" android app by closing all activities, or by implementing double back idiom on start activity. Its better to think that android app runs all the time after it is started. By closing all the activities your process might still be running for long time. Android might kill your process after some time, or keep it for long time.
So what would happen if I never shutdown ExecutorService on an Android application?
waste of resources, android might be more likely kill your process making it longer for your app to be started next time (but how much longer, I have no idea) - but as always it depends on your application.
If you for some reasons you dont control incoming tasks - then by shuting down your executor you also prevent new tasks to be processed when your app should be closed, you can find method for this here.
This might be usefull when your executor is inside service, and you want to stop that service. Then its suggested to gracefully release resoures. Also you might have some code that depends on all tasks to be finished, etc...
I'm writing an android app that involves one AudioTrack and one AudioRecord. They run in two different threads, and both of them need to continue to run and not being killed when low memory/CPU even if the app is running in the background. I searched about this and I know I could probably use AsyncTask (just like in music streaming app). However, I'm no exactly sure how to do it because the thread that runs AudioTrack is first created (once a certain button on the main activity is pressed), then this thread will create another thread that runs AudioRecord (by creating a Runnable).
I searched about this and I know I could probably use AsyncTask (just like in music streaming app)
No. Your issue is not the threads, but the process.
both of them need to continue to run and not being killed when low memory/CPU even if the app is running in the background
Strictly speaking, that is not possible. The closest that you will get will be to use a Service that in turn uses startForeground() to indicate that it has foreground priority. That will minimize the probability that Android will terminate your process due to low memory conditions, but it will not eliminate it.
Also, please note that you will need the CPU to be powered on to perform your audio tasks. That, in turn, will require a WakeLock. This is going to seriously hammer the user's battery, to the point where you should advise users to keep the device on a charger. That will be particularly important in the future, where the "Doze mode" of the upcoming "M" Android release will block your use of WakeLocks if the device is idle, unmoving, and not on a charger.
In my application there's an AsyncTask which runs in the background for much time. The problem is that in low memory situations it's killed by the VM, is there a way to make the application's priority higher, so that it would be harder to kill? Should I use a service instead? My only target is to make it difficult to kill, any advice or guidance would be greatly appreciated, thank you.
I would advice you to make it a service and use startForeground() which will make it a little more resistant. But even then it might get stopped on low memory.
No, there's no as everyone would abuse this otherwise. If OS kills your service then it got a reason for this. If condition permits and your service qualifies, it will be restarted if Android thinks it shall do so.
If your service is killed, then it's restarted by the system as soon as resources allow.
So, make it a service (it shouldn't be a foreground service, if it doesn't do anything decidedly user-oriented like playing music), but a service that can save its state (onMemoryLow() and onDestroy() methods). So after the restart it can resume its process with the user being none the wiser.
In my Android app, I need a certain bit of code to execute every minute, whether the phone is active or not.
(For those curious, the app is meant for a personal project, a "talking" clock which will need to check every minute if that time has a corresponding sound file to play. It's not something I plan to release to the world, so battery considerations are not in play.)
My current approach is to use Timer.scheduleAtFixedRate() to schedule a task.
This seems to work whenever I am looking at the app, and interacting with it occasionally to keep the screen from blanking, but if the phone turns the screen off to save power, it seems like my call happens sporadically.
I tried setting the interval to be every 30 seconds, but even then it seems like I miss some minutes. Are there specific considerations to using Timer on Android? Is there a better way to achieve what I need?
Question: are you 100% absolutely sure you need to be doing this every minute? It just sounds to me that you'll be hogging the battery like crazy and will get quite a few unhappy users.
But if you answer yes to that question:
After your activity is paused, there's not guarantee from the system that anything on it (including your task) will be kept running; that way as soon as the systems needs a couple of megabytes to do anything it will kill your activity and stop your timer.
You should implement the timer/task in a Service. Services are much less likely to be killed by the system and you might ask that if the system needs to kill it to re-created it as soon as possible.
Have you tried using AlarmManager, this will let you do a task every X amount of time even if the phone is in standby mode or off
Here are the docs for it
If you want a nice example of using an AlarmManager, here it is... This one does not work if the phone is turned off but you can enable this easily if you want
I need my Android app to save it's state to disk when its activity is put in the background or killed. It's been suggested that I start a thread when onPause() is called and perform any expensive I/O procedures there (see Saving/loading document state quickly and robustly for image editor).
In what situations will the OS kill the thread and how commonly do these situations occur?
I assume it will be like how Activities are dealt with where the OS can arbitrary decide to kill the thread but will mostly only do this when resources are extremely limited. It would be nice to find some specific documentation of this though.
From playing around, with some test code, a background thread started in onPause() will run indefinitely in the background on my device (I tried loading lots of apps and couldn't get it to be killed).
For my specific app, I'm writing a bitmap editor where I'm using the Command pattern and the Memento pattern to allow undo and redo of edits. I'd like the user to be able to undo/redo their edits even e.g. the user gets a phone call and the activity is killed when it is put in the background. The best solution I can think of is to use a background thread to constantly save my command and memento objects to disk during application use and to finish up saving any objects that are left in a background thread if onPause is called. In the worse case, if the thread is killed I'll only lose some edits.
In what situations will the OS kill the thread and how commonly do these situations occur?
The OS will not kill the thread, unless it is killing the process -- Android does not do anything with threads you create yourself. If you are the foreground process, you will not be killed. The odds of Android killing the process within a few seconds of you losing the foreground (after onPause()) are miniscule. The documentation on process lifetime -- what there is of it -- can be found here.
Your thread may be killed at any time after the activity is destroyed, or it may never be killed. Depending upon such a thread is very bad form -- you could end up with a half-completed operation, or with a thread that sticks around forever.
If you wish to perform a background operation that continues even when there is no foreground activity, you almost always want to run it inside a Service. On the other hand, the service is less likely to be killed, but there's no guarantee unless you use "startForeground". This will end up displaying a notification to the user that something is happening in the background, but as far as I know it's the only way of running an asynchronous background thread that is guaranteed not to be killed.
Honestly, the right answer is to make sure that there is never any temporary process state that will take a long time to save. If you are having to write a large file to reflect a few user changes, consider maintaining a "transaction log" which you can use to create a restartable save operation. Given this, you can safely run your saves in a service and know that even if it gets killed, it will be automatically restarted when resources become available.
Normally, saving your state in onPause is the right thing to do if it's quick. I don't think it's clearly documented when a process is killed, but you sometimes see it in logcat when you run some demanding apps (say, after running Google Earth and Browser).
There's also an option in the Android DevTools to automatically destroy activities as you navigate away from them, although that probably doesn't extend to the process. (DevTools are on the emulator, and on some rooted phones).
I think your approach sound reasonable - use a low-priority thread to constantly update the save data, and give it normal priority in onPause, and set a flag in onPause that tells it to terminate after it finishes.
Obviously, you'll need to make sure you don't run into synchronization issues if you get to onResume immediately after onPause (i.e. while the thread is still busy saving).