How can I run code on a background thread on Android?
Solution 1:
IF you need to:
execute code on a background Thread
execute code that DOES NOT touch/update the UI
execute (short) code which will take at most a few seconds to complete
THEN use the following clean and efficient pattern which uses AsyncTask:
AsyncTask.execute(new Runnable() {
@Override
public void run() {
//TODO your background code
}
});
Solution 2:
Remember Running Background, Running continuously are two different tasks.
For long-term background processes, Threads aren't optimal with Android. However, here's the code and do it at your own risk...
Remember Service or Thread will run in the background but our task needs to make trigger (call again and again) to get updates, i.e. once the task is completed we need to recall the function for next update.
Timer (periodic trigger), Alarm (Timebase trigger), Broadcast (Event base Trigger), recursion will awake our functions.
public static boolean isRecursionEnable = true;
void runInBackground() {
if (!isRecursionEnable)
// Handle not to start multiple parallel threads
return;
// isRecursionEnable = false; when u want to stop
// on exception on thread make it true again
new Thread(new Runnable() {
@Override
public void run() {
// DO your work here
// get the data
if (activity_is_not_in_background) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// update UI
runInBackground();
}
});
} else {
runInBackground();
}
}
}).start();
}
Using Service: If you launch a Service it will start, It will execute the task, and it will terminate itself. after the task execution. terminated might also be caused by exception, or user killed it manually from settings. START_STICKY (Sticky Service) is the option given by android that service will restart itself if service terminated.
Remember the question difference between multiprocessing and multithreading? Service is a background process (Just like activity without UI), The same way how you launch thread in the activity to avoid load on the main thread (Activity thread), the same way you need to launch threads(or async tasks) on service to avoid load on service.
In a single statement, if you want a run a background continues task, you need to launch a StickyService and run the thread in the service on event base
Solution 3:
Simple 3-Liner
A simple way of doing this that I found as a comment by @awardak in Brandon Rude's answer:
new Thread( new Runnable() { @Override public void run() {
// Run whatever background code you want here.
} } ).start();
I'm not sure if, or how, this is better than using AsyncTask.execute
but it seems to work for us. Any comments as to the difference would be appreciated.
Thanks, @awardak!
Solution 4:
I want some code to run in the background continuously. I don't want to do it in a service. Is there any other way possible?
Most likely mechanizm that you are looking for is AsyncTask
. It directly designated for performing background process on background Thread. Also its main benefit is that offers a few methods which run on Main(UI) Thread and make possible to update your UI if you want to annouce user about some progress in task or update UI with data retrieved from background process.
If you don't know how to start here is nice tutorial:
Note: Also there is possibility to use IntentService
with ResultReceiver
that works as well.
Solution 5:
Today I was looking for this and Mr Brandon Rude gave an excellent answer. Unfortunately, AsyncTask
is now deprecated. You can still use it, but it gives you a warning, which is very annoying. So an alternative is to use Executors
like this (in kotlin
):
Executors.newSingleThreadExecutor().execute(Runnable {
// todo: do your background tasks
runOnUiThread{
// update ui if you are in an activity
}
/*
requireActivity().runOnUiThread {
// update views / ui if you are in a fragment
}
*/
})
And in java
it looks like this:
Executors.newSingleThreadExecutor().execute(() -> {
// todo: background tasks
runOnUiThread(() -> {
// todo: update your ui / view in activity
});
/*
requireActivity().runOnUiThread((Runnable) () -> {
// todo: update your ui / view in Fragment
});
*/
});