MultiThreading in Android with Examples


Introduction

An essential component of developing for Android is multithreading, which enables you to carry out multiple operations at once. Multithreading can be implemented in Android using a variety of methods, including AsyncTask, Handler, and Thread.

In this article, we will be discussing the various components, advantages, disadvantages, and use cases for Multithreading in Android.

Components of Multithreading in Android

Async Task

Android operating system has a class called AsyncTask that offers a quick and easy way for implementing experience actions lacking the need to specifically oversee strings and those who handle them. It has three different approaches: doInBackground(), onPostExecute(), and onPreExecute().

Example

Programming language used: Java

The Java code below demonstrates the usage of AsyncTask in Android for downloading an image from a specified URL and displaying it in an ImageView. The AsyncTask subclass, ImageDownloadTask, extends AsyncTask with type parameters <String, Void, Bitmap>, representing the input URL, progress update type, and result bitmap type respectively.

public class ImageDownloadTask extends AsyncTask<String, Void, Bitmap> {

   private ImageView imageView;

   public ImageDownloadTask(ImageView imageView) {
      this.imageView = imageView;
   }

   @Override
   protected Bitmap doInBackground(String... urls) {
      String imageUrl = urls[0];
      Bitmap bitmap = null;

      try {
         URL url = new URL(imageUrl);
         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
         connection.setDoInput(true);
         connection.connect();

         InputStream inputStream = connection.getInputStream();
            bitmap = BitmapFactory.decodeStream(inputStream);
      } catch (IOException e) {
         e.printStackTrace();
      }

      return bitmap;
   }

   @Override
   protected void onPostExecute(Bitmap bitmap) {
      if (bitmap != null) {
         imageView.setImageBitmap(bitmap);
      }
   }
}

Input

To use this AsyncTask, you can create an instance and execute it as follows (in Java)−

String imageUrl = "https://example.com/image.jpg";
ImageView imageView = findViewById(R.id.imageView);

ImageDownloadTask imageDownloadTask = new ImageDownloadTask(imageView);
imageDownloadTask.execute(imageUrl);

Expected Output

The AsyncTask will download the image from the specified URL in the background. Once the download is complete, the onPostExecute() method will be called, and the downloaded image will be displayed in the ImageView passed to the ImageDownloadTask.

Handler

An Android device class called a Handler may be utilized for inter-thread communication. It may be employed to transfer functional elements and communications among processes.

Example (in Java)

In the example code below, the background thread will execute the performBackgroundTask() method to perform some background tasks. Once the tasks are complete, a message is sent to the mainHandler.

public class MessageHandler extends Handler {
   @Override
   public void handleMessage(@NonNull Message msg) {
      super.handleMessage(msg);

      // Process the message and update UI
      String message = (String) msg.obj;
      textView.setText(message);
   }
}

Input

To use the Handler, you can send messages from a separate thread as follows (in Java)

Handler mainHandler = new MessageHandler();

Thread backgroundThread = new Thread(new Runnable() {
   @Override
   public void run() {
      // Perform background tasks
      String result = performBackgroundTask();

      // Send message to update UI
      Message message = Message.obtain();
      message.obj = result;
      mainHandler.sendMessage(message);
   }
});

backgroundThread.start();

Expected Output

The handleMessage() method in MessageHandler will be called on the main UI thread, and the TextView (named textView in the example) will be updated with the result message.

Thread

In Android phones and tablets a thread is a fundamental unit of the executioner's Long-running assignments are carried out using it as it runs in background mode.

Example (in Java)

In this example, the performBackgroundTask() method represents the actual background task that you need to execute. The runOnUiThread() method ensures that the UI update is performed on the main UI thread.

Thread backgroundThread = new Thread(new Runnable() {
   @Override
   public void run() {
      // Perform background tasks
      String result = performBackgroundTask();

      // Update UI using runOnUiThread or posting to a Handler
      runOnUiThread(new Runnable() {
         @Override
         public void run() {
            textView.setText(result);
         }
      });
   }
});

backgroundThread.start();

Expected Output

The background thread will execute the performBackgroundTask() method to perform some background tasks. Once the tasks are complete, the UI update is performed using the runOnUiThread() method. The TextView (named textView in the example) will be updated with the result message.

Use Cases for Multithreading in Android

Background Tasks − Multithreading is commonly used to perform background tasks that don't require direct interaction with the user interface. For example, downloading files, synchronizing data with a server, or performing complex calculations can be offloaded to separate threads to prevent blocking the main UI thread and provide a smooth user experience.

Network Requests − When making network requests, such as fetching data from an API or uploading files, multithreading allows you to perform these operations concurrently. You can initiate network requests on separate threads, ensuring that the UI remains responsive while waiting for responses from the server.

Database Operations − Multithreading is useful for handling database operations, especially when dealing with large datasets or complex queries. By executing database transactions on separate threads, you can prevent UI freezing and enable concurrent database operations.

Image Processing − Performing image processing tasks, such as resizing, cropping, or applying filters to images, can be computationally expensive. Multithreading enables you to distribute these tasks across multiple threads, improving the performance and responsiveness of your app.

Audio/Video Playback − When playing audio or video files in an Android app, multithreading is crucial to ensure smooth playback. Decoding and rendering audio or video data can be done on separate threads, allowing the main thread to handle user interactions and UI updates.

File I/O Operations − Reading from or writing to files on the device's storage can be time-consuming, especially for large files. Multithreading can be used to carry out file I/O operations in the background, preventing UI freezing and providing a better user experience.

Concurrent Processing − Multithreading enables concurrent execution of multiple tasks, which can be useful in scenarios where you need to perform several operations simultaneously. For example, if you have a music app, you can use multithreading to download album art, fetch song metadata, and play audio all at once.

Real-time Updates − Multithreading can be utilized to receive real-time updates from various sources, such as chat messages or live data feeds. By running dedicated threads for handling incoming updates, you can keep the UI responsive and ensure the timely delivery of information.

CPU-Intensive Tasks − For computationally intensive tasks that don't require immediate UI feedback, multithreading can leverage the device's CPU resources effectively. These tasks can include complex calculations, data analysis, or simulations.

Game Development − Multithreading is particularly valuable in game development, where various tasks, such as rendering graphics, updating game logic, and handling user input, need to be performed concurrently. By distributing these tasks across threads, you can achieve smooth gameplay and responsive controls.

Conclusion

In the final analysis, multithreading in Android could have a big impact on your app by improving adaptability, efficiency, and the capacity for backdrop operations. It enables more effective importance segregation, asynchronous implementation, and parallel processing. Nevertheless, multithreading also adds complexity as well. necessitates cautious management of resources, and can result in problems like race conditions, deadlocks, and increased memory usage. It can be difficult to debug multithreaded code and manage synchronization. You can maximize the benefits of multithreading while minimizing any potential drawbacks by being aware of its benefits and drawbacks and adhering to best practices. When used properly, multithreading is a potent tool, but to guarantee the seamless and effective performance of assignments in your Android usage, meticulous preparation, deployment, and evaluation are necessary.

Updated on: 14-Jul-2023

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements