Android Thread Pool has runnables building up without execution after background state - android

My application has a thread pool that creates 3 simultaneous threads. As I invoke runnables, they are added to my thread pool.
My problem happens when the application goes to the background for a while. Eventually, my threads stop executing the runnables in my pool and the pool just continues to grow. Even if I bring my application back to the foreground, my threads do not start running again.
My theory is that when my application goes to the background that my threads are being killed. I'm not sure by what and I'm also not sure of a good way of determining whether my threads are killed so that I can start them again.
Do you have any suggestions as to something I can look for to determine whether or not a thread has been killed?

You can't use a thread pool to execute code in the background because the Android activity lifecycle won't consider your app to be active, and will kill your process (including all threads) eventually after you lose UI focus. What you want is an Android Service which has a different lifecycle. To do things like this we use a local service with a Handler and a HandlerThread that we can post Runnables into. You'll probably want something similar.
Note: Every time I do this I feel like there must be an easier way, so it might be worth searching if someone has simplified this pattern.

Related

Can a background thread exist without the main thread?

If I remove the app from the background/recent app list, the UI thread also stops so that system can reclaim the memory associated with the UI. Now consider a case where a PeriodicWorkRequest is triggered which in turn starts a worker (after the app is removed from the background/recent apps list). The worker implicitly runs on a separate background thread and is performing the assigned tasks. But is the UI/Main thread also created along with the worker thread?
An app can exist with no activity. It can have other components like services etc with no UI. In this case, does the UI/Main thread still exist?
Or in any other scenario, can a process exist with no UI/Main thread, just a worker thread?
In android things get complicated really fast.
Android is a fragmented ecosystem and some OEM perform some device alterations that result in different behaviors across devices for example when you close an app instead of doing a grace shutdown it does a kill to provide an immediate effect. even background workers are not very guaranteed, read some more here
Background workers are you best bet.

Android Daemon type functionality

If I spawn a thread via AsyncTask from the UI thread, is this thread killed when the UI thread terminates?
My AsyncTask (spawned fom UI) performs operations and then calls the Notification Manager as appropriate (part of my applications functionality). This works well, but notifications cease when the application exits, and I am assuming this is because the UI thread has terminated, therefore so do the children.
I did consider a service (assuming initially it would perform similar to a daemon) but then read that these run on the UI/main thread so would not be persistent across the UI thread termination.
My question really is how can I get the functionality of a daemon spawned from an Android app? I don't need permissions outside the spawning parent process, and it doesn't need to be persistent across reboots.
POSIX API'ish threads through the NDK or am I completely wrong?
Only spent a couple of days with Android so still trying to feel my way around. Many thanks!
Threads execute within a process. Android suspends (for later reuse) or kills an application's process when it's destroyed, which takes all threads with it. So the daemon would have to be a disconnected process, not a thread. Android is deliberately set up to prevent you from starting these (though sub-processes are straightforward with Runtime.exec() and its relatives). I think you can do what you want by fork/exec()'ing in the NDK, but the phone will have to be rooted to run the resulting app, which creates many problems. Not least is that warranty is often voided for a rooted phone.
If I spawn a thread via AsyncTask from the UI thread, is this thread killed when the UI thread terminates?
Not automatically and not immediately. The thread will run to completion, or until Android terminates the process, whichever comes first.
I did consider a service (assuming initially it would perform similar to a daemon) but then read that these run on the UI/main thread so would not be persistent across the UI thread termination.
Services are not really a "daemon" in classic Linux sense. A service is automatically in the background from a UI standpoint. It is not automatically in the background from a threading standpoint. Any work the service does that will take some time should be done on a background thread. The difference is that with a service running, Android will not be as prone to terminate your process quite as quickly.
My question really is how can I get the functionality of a daemon spawned from an Android app?
That depends on what features of a "daemon" you are trying to obtain, which you neglected to describe in your question.
POSIX API'ish threads through the NDK
That will do you no good. Your threads will still be terminated when your process terminates.
I had to implement almost the same functionality: firing notifications form background.
It's rather simple: start a service and spawn a new thread from within the service.
There are many scenario's where Android platform offers some uot-of-the-box goodies where you do not ecessarily have to start threads yourself.
For example:
if your thread should just wait for something you can schedule periodic 'wake up' events with AlarmManager which will take care of running in background
or if you need to synchronize data in background with back-end you can use SyncAdapter API which also takes care of running in background.
As CommonsWare just suggested:
That depends on what features of a "daemon" you are trying to obtain, which you neglected to describe in your question.

Difference between Android application spawning thread vs. Service?

I have an Android application that has a need to perform work in the background and on a separate thread. For my first proof-of-concept I subclassed the Application class and inside onCreate() I spawn a Thread that does the background work. This works just great. However, I just realized that in the past I've used a service for situations like this.
The question is, is there a reason to do work on a Thread spawned from a Service instead of a Thread spawned by Application.onCreate()? The Service is supposed to perform "background" work (it uses the UI thread unless a Thread is used, I know) that is independent of the Activity and can run while no Activity is visible. Using an Application-based thread seems to accomplish all this just as well. By not using a Service it actually removes complexity because the Activity just accesses the Application singleton. As far as I know I have no need to bind to the Service.
Will I get bit by lifecycle corner cases that using a Service would prevent? That's the only concern I have over this approach, but otherwise I'm not sold on the benefits of a Service.
The difference would be if you want the thread to run in the background only when the Activity is running or if you want it to continue to run when the user leaves.
Services are capable of running in the background even when the Activity is no longer available. They are intended to be used when your app should continue to do work without any user involvement in the near future. If you run the Thread in the Service, the thread will continue to run even when the user leaves the app. This can be beneficial sometimes as the user may want you to keep downloading a really large file but doesn't want the app to continue to run in the foreground. Then, a few hours (days, months, years) later the user can re-enter the app to read the file.
If, however, you're using a thread that needs to constantly update the UI based on results, it may be more beneficial to launch it within the Activity since it has no real purpose to run in a Service. It also may be easier in your program for your Thread to talk to the UI if it's in the Activity rather than the Service. (There may be some performance benefits as Android doesn't have to handle yet another Service on it's list, but that's purely speculation on my part. I have no proof of it.)
NOTE: Threads created in Activities will still continue to run even when the Activity quits. However, this is merely because the app is still in memory. The Activity and it's thread are on a higher priority to be deleted from memory than a Service thread when the Activity is no longer within view.
If your application is not either in the foreground, or visible, then it's more likely to be killed off by the system. If you run your code as a service, rather than a thread spawned by a background process, then your task will survive for longer. No guarantees, so you still need to manage the process lifecycle properly, but running as a service is likely to give more reliable results.
See http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html

Necessary to quit a HandlerThread?

My application makes use of a HandlerThread for a few operations shared across components that need to run on a background thread. Most of the time this thread will be in its wait state.
Can I leave this HandlerThread running (waiting) in my application, sending messages to it whenever necessary, but never quitting it via HandlerThread.getLooper().quit()? This could mean that this HandlerThread would continue to exist in its wait state even after all of my application components have been destroyed.
Initially this seemed like a big no to me—something I definitely would not want to do—but I'm not sure now. When Android kills my process, like it will do when it needs to free up CPU time or memory, it'll end this thread along with my UI thread. Additionally, the thread will be waiting, so it wont be consuming any CPU time. And beyond that, my application makes use of many AsyncTasks, which I know utilize a thread pool. From my understanding, AsyncTask utilizes ThreadPoolExecutor, which does not adhere to any application lifecycle callbacks (the threads in the pool when not in use, just sit waiting).
So my question is, can I use a HandlerThread across multiple application components, never (or rarely) quitting it, and leaving it waiting when not in use, without suffering terrible ill effects?
My personal preference is to create a new thread whenever there is a need for it and clean it up when it's done. This way I don't have any problems with multiple components trying to use the same thread at the same time and I keep a "clean ship". Also Android has the nice AsyncTask which makes this easy for you.
That being said, I see no reason why you can't reuse your handlerthread for multiple components, provided you regulate access to the thread AND clean it up properly when your activities are destroyed. If I understand this post correctly, your thread may keep running even if all your activities are terminated because your process may keep on running. To solve this, you can set your thread as a daemon thread. Daemon threads are automatically destroyed when the last non-daemon thread in your application is finished.
BTW, alternatively you also might want to consider using a ThreadPoolExecutor

Thread started by an application in android

If I raise a thread in via an Application in Android, how long does the thread life and is active?
Does a thread continue to live when the user leaves the application. If so for how long?
Until the Thread completes. You should look into AsyncTask class instead of regular Threads though.
Yeah in Android threads are like the old-fashion Java thread. They do not have a predefined lifecylvce like Services, Activities etc. If you start a new thread you must also be responsible of its lifecycle (i.e. terminate it when you do not need it anymore and keep it alive untill you need it).
EDIT: see here and this other question. As I was saying, the thread remains alive untill it has work to do. Regard that if the process of your application is destroied by the O.S. then also the thread you have created will be destroyed as well.

Categories

Resources