Android Tutorial
Software Setup and Configuration
Android Studio
File Structure
Components
Core Topics
Layout
View
Button
Intent and Intent Filters
Toast
RecyclerView
Fragments
Adapters
Other UI Component
Image Loading Libraries
Date and Time
Material Design
Bars
Working with Google Maps
Chart
Animation
Database
Advance Android
Jetpack
Architecture
App Publish
App Monetization
Multithreading is a powerful tool in Android to avoid performing resource-intensive tasks on the main (or UI) thread, which can freeze the UI and make applications unresponsive. There are various mechanisms in Android to handle multithreading:
The most basic way is to use the Thread
class.
val thread = Thread { // Perform some background work here. } thread.start()
However, when using threads directly, you need to handle thread synchronization and communication back to the main thread manually.
AsyncTask allows you to perform background operations and then publish the results on the UI thread. However, starting from Android R, AsyncTask
is deprecated.
private class MyTask : AsyncTask<Void, Void, String>() { override fun doInBackground(vararg params: Void?): String { // Perform background work. return "Result" } override fun onPostExecute(result: String) { // This runs on the UI thread, use result here. } }
To execute: MyTask().execute()
Handlers are used to send and process Message
and Runnable
objects associated with a thread's MessageQueue
.
val handler = Handler(Looper.getMainLooper()) val runnable = Runnable { // Execute tasks } // Post the Runnable to be executed handler.post(runnable)
This is a handy class for starting a new thread that has a looper.
val handlerThread = HandlerThread("BackgroundHandlerThread") handlerThread.start() val handler = Handler(handlerThread.looper) handler.post { // Background task }
This provides a higher-level replacement for AsyncTask
, allowing you to manage a pool of worker threads.
val executor: Executor = Executors.newSingleThreadExecutor() executor.execute { // Perform background work here. }
With Kotlin, coroutines provide a more efficient and simpler way to handle asynchronous tasks and multithreading.
GlobalScope.launch(Dispatchers.IO) { // Perform background work here. withContext(Dispatchers.Main) { // Update UI on main thread } }
It's a library for composing asynchronous and event-based programs using observable sequences.
Observable.fromCallable { // Background work } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { result -> // Update UI with result }
Note: Always remember to manage the lifecycle of threads, especially when they are linked with lifecycle-aware components like Activities or Fragments, to prevent memory leaks and unexpected behavior. Using higher-level tools like Coroutines or RxJava makes lifecycle management easier and more intuitive.
Android AsyncTask example code:
public class MyAsyncTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... params) { // Background task return "Task completed"; } @Override protected void onPostExecute(String result) { // UI thread, update UI with the result textView.setText(result); } } // Execute the AsyncTask new MyAsyncTask().execute();
Using threads and handlers in Android app development:
new Thread(() -> { // Background task String result = performBackgroundTask(); // Update UI using handler handler.post(() -> textView.setText(result)); }).start();
Concurrency in Android with Java threads:
new Thread(() -> { // Background task }).start();
Working with ThreadPoolExecutor in Android:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, // Core pool size 5, // Maximum pool size 60, // Keep-alive time in seconds TimeUnit.SECONDS, new LinkedBlockingQueue<>() ); executor.execute(() -> { // Background task });
Thread synchronization examples in Android:
private static final Object lock = new Object(); synchronized void synchronizedMethod() { // Code requiring synchronization }
Handling background tasks with AsyncTaskLoader in Android:
public class MyLoader extends AsyncTaskLoader<String> { @Override public String loadInBackground() { // Background task return "Loader completed"; } } // Initialize and start the loader LoaderManager loaderManager = getSupportLoaderManager(); Loader<String> loader = loaderManager.initLoader(1, null, new MyLoaderCallbacks()); loader.forceLoad();
These examples cover AsyncTask, threads and handlers, concurrency with Java threads, ThreadPoolExecutor, thread synchronization, AsyncTaskLoader, and multithreading patterns and anti-patterns in Android. Choose the appropriate approach based on the requirements of your background tasks.