Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Simplifying Android Development with Coroutines and Flows
Simplifying Android Development with Coroutines and Flows

Simplifying Android Development with Coroutines and Flows: Learn how to use Kotlin coroutines and the flow API to handle data streams asynchronously in your Android app

eBook
$16.99 $24.99
Paperback
$30.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Table of content icon View table of contents Preview book icon Preview Book

Simplifying Android Development with Coroutines and Flows

Chapter 1: Introduction to Asynchronous Programming in Android

There are Android applications that work on their own. But most apps retrieve data from or send data to a local database or a backend server. Examples of these include fetching posts from a social network, saving your favorites from a list, uploading an image, or updating your profile information. These tasks and other resource-intensive computations may happen instantly or take a while to finish. Factors such as internet connection, device specifications, and server settings affect how long these operations take.

Long-running operations must not be performed on the main UI thread as the application will be blocked until they are completed. The application might become unresponsive to the users. Users may not be aware of what’s happening, and this might prompt them to close the app and reopen it (canceling the original task or doing it again). The app can also suddenly crash. Some users might even stop using your app if this happens frequently.

To prevent this from happening, you need to use asynchronous programming. Tasks that can take an indefinite amount of time must be done asynchronously. They must run in the background, parallel to other tasks. For example, while posting information to your backend server, the app displays the UI, which the users can interact with. When the operation finishes, you can then update the UI or notify the users (with a dialog or a snackbar message).

With this book, you will learn how to simplify asynchronous programming in Android using Kotlin coroutines and flows.

In this chapter, you will first start by revisiting the concept of asynchronous programming. After that, you will look into the various ways it is being done now in Android and how they may no longer be the best way moving forward. Then, you will be introduced to the new, recommended way of performing asynchronous programming in Android: coroutines and flows.

This chapter covers three main topics:

  • Asynchronous programming
  • Threads, AsyncTasks, and Executors
  • The new way to do it – coroutines and flows

By the end of this chapter, you will have a basic understanding of asynchronous programming, and know how to do it in Android using threads, AsyncTasks, and Executors. Finally, you will discover Kotlin coroutines and flows as these are the recommended ways of doing asynchronous programming in Android.

Technical requirements

You will need to download and install the latest version of Android Studio. You can find the latest version at https://developer.android.com/studio. For an optimal learning experience, a computer with the following specifications is recommended: Intel Core i5 or equivalent or higher, 4 GB RAM minimum, and 4 GB available space.

The code examples for this book can be found on GitHub at https: github.com/PacktPublishing/Simplifying-Android-Development-with-Coroutines-and-Flows.

Understanding asynchronous programming

In this section, we will start by looking at asynchronous programming. Asynchronous programming is a programming method that allows work to be done independently of the main application thread.

A normal program will run sequentially. It will perform one task and move to the next task after the previous one has finished. For simple operations, this is fine. However, there are some tasks that might take a long time to finish, such as the following:

  • Fetching data from or saving data to a database
  • Getting, adding, or updating data to a network
  • Processing text, images, videos, or other files
  • Complicated computations

The app will look frozen and unresponsive to the users while it is performing these tasks. They won’t be able to do anything else in the app until the tasks are finished.

Asynchronous programming solves this problem. You can run a task that may be processed indefinitely on a background thread (in parallel to the main thread) without freezing the app. This will allow the users to still interact with the app or the UI while the original task is running. When the task has finished or if an error was encountered, you can then inform the user using the main thread.

A visual representation of asynchronous programming is shown in the following figure:

Figure 1.1 – Asynchronous programming

Figure 1.1 – Asynchronous programming

Task 1 and Task 2 are running on the main thread. Task 2 starts Task 3 on the background thread. While Task 3 is running, the main thread can continue to perform other tasks, such as Task 4. After Task 3 is done, it will return to the main thread.

Asynchronous programming is an important skill for developers to have, especially for mobile app development. Mobile devices have limited capabilities and not all locations have a stable network connection.

In Android, if you run a task on the main thread and it takes too long, the app can become unresponsive or look frozen. The app can also crash unexpectedly. You will likely get an Application Not Responding (ANR) error, as shown in the following screenshot:

Figure 1.2 – An ANR dialog

Figure 1.2 – An ANR dialog

Starting with Android 3.0 (Honeycomb), running a network operation on the main thread will cause android.os.NetworkOnMainThreadException, which will crash your app.

ANR dialogs and crashes can annoy your users. If they happen all the time, they might stop using your app altogether and choose another app. To prevent them in your app, you must run tasks that can take a long period of time on the background thread.

In this section, you revisited the concept of asynchronous programming and how you can use it to run long-running tasks without freezing the app. You will explore various approaches for using asynchronous programming in Android in the next section.

Exploring threads, AsyncTasks, and Executors

There are many ways you can run tasks on the background thread in Android. In this section, you are going to explore various ways of doing asynchronous programming in Android, including using threads, AsyncTask, and Executors. You will learn how to start a task on the background thread and then update the main thread with the result.

Threads

A thread is a unit of execution that runs code concurrently. In Android, the UI thread is the main thread. You can perform a task on another thread by using the java.lang.Thread class:

private fun fetchTextWithThread() {
  Thread {
        // get text from network
        val text = getTextFromNetwork()
  }.start()
}

To run the thread, call Thread.start(). Everything that is inside the braces will be performed on another thread. You can do any operation here, except updating the UI, as you will encounter NetworkOnMainThreadException.

To update the UI, such as displaying the text fetched in a TextView from the network, you would need to use Activity.runOnUiThread(). The code inside runOnUIThread will be executed in the main thread, as follows:

private fun fetchTextWithThread() {
  Thread {
          // get text from network
          val text = getTextFromNetwork()
    runOnUiThread {
        // Display on UI
        displayText(text)
    }
  }.start()
}

runOnUIThread will perform the displayText(text) function on the main UI thread.

If you are not starting the thread from an activity, you can use handlers instead of runOnUiThread to update the UI, as seen in Figure 1.3:

 Figure 1.3 – Threads and a handler

Figure 1.3 – Threads and a handler

A handler (android.os.Handler) allows you to communicate between threads, such as from the background thread to the main thread, as shown in the preceding figure. You can pass a looper into the Handler constructor to specify the thread where the task will be run. A looper is an object that runs the messages in the thread’s queue.

To attach the handler to the main thread, you should use Looper.getMainLooper(), like in the following example:

private fun fetchTextWithThreadAndHandler() {
  Thread {
    // get text from network
           val text = getTextFromNetwork()
    Handler(Looper.getMainLooper()).post {
      // Display on UI
      displayText(text)
    }
  }.start()
}

Handler(Looper.getMainLooper()) creates a handler tied to the main thread and posts the displayText() runnable function on the main thread.

The Handler.post (Runnable) function enqueues the runnable function to be executed on the specified thread. Other variants of the post function include postAtTime(Runnable) and postDelayed (Runnable, uptimeMillis).

Alternatively, you can also send an android.os.Message object with your handler, as shown in Figure 1.4:

Figure 1.4 – Threads, handlers, and messages

Figure 1.4 – Threads, handlers, and messages

A thread’s handler allows you to send a message to the thread’s message queue. The handler’s looper will execute the messages in the queue.

To include the actual messages you want to send in your Message object, you can use setData(Bundle) to pass a single bundle of data. You can also use the public fields of the message class (arg1, arg2, and what for integer values, and obj for an object value).

You must then create a subclass of Handler and override the handleMessage(Message) function. There, you can then get the data from the message and process it in the handler’s thread.

You can use the following functions to send a message: sendMessage(Message), sendMessageAtTime(Message, uptimeMillis), and sendMessageDelayed(Message, delayMillis). The following code shows the use of the sendMessage function to send a message with a data bundle:

private val key = "key"
private val messageHandler = object :
   Handler(Looper.getMainLooper()) {
    override fun handleMessage(message: Message) {
    val bundle = message.data
    val text = bundle.getString(key, "")
    //Display text
    displayText(text)
  }
}
private fun fetchTextWithHandlerMessage() {
  Thread {
    // get text from network
    val text = getTextFromNetwork()
    val message = handler.obtainMessage()
  
    val bundle = Bundle()
    bundle.putString(key, text)
    message.data = bundle
    messageHandler.sendMessage(message)
  }.start()
}

Here, fetchTextWithHandlerMessage() gets the text from the network in a background thread. It then creates a message with a bundle object containing a string with a key of key to send that text. The handler can then, through the handleMessage() function, get the message’s bundle and get the string from the bundle using the same key.

You can also send empty messages with an integer value (the what) that you can use in your handleMessage function to identify what message was received. These send empty functions are sendEmptyMessage(int), sendEmptyMessageAtTime(int, long), and sendEmptyMessageDelayed(int, long).

This example uses 0 and 1 as values for what (“what” is a field of the Message class that is a user-defined message code so that the recipient can identify what this message is about): 1 for the case when the background task succeeded and 0 for the failure case:

private val emptymesageHandler = object :
  Handler(Looper.getMainLooper()) {
  override fun handleMessage(message: Message) {
    if (message.what == 1) {
      //Update UI
    } else {
      //Show Error
    }
  }
}
private fun fetchTextWithEmptyMessage() {
  Thread {
    // get text from network
...
    if (failed) {  
      emptyMessageHandler.sendEmptyMessage(0)
    } else {
      emptyMessageHandler.sendEmptyMessage(1)
    }
  }.start()
}

In the preceding code snippet, the background thread fetches the text from the network. It then sends an empty message of 1 if the operation succeeded and 0 if not. The handler, through the handleMessage() function, gets the what integer value of the message, which corresponds to the 0 or 1 empty message. Depending on this value, it can either update the UI or show an error to the main thread.

Using threads and handlers works for background processing, but they have the following disadvantages:

  • Every time you need to run a task in the background, you should create a new thread and use runOnUiThread or a new handler to post back to the main thread.
  • Creating threads can consume a lot of memory and resources.
  • It can also slow down your app.
  • Multiple threads make your code harder to debug and test.
  • Code can become complicated to read and maintain.

Using threads makes it difficult to handle exceptions, which can lead to crashes.

As a thread is a low-level API for asynchronous programming, it is better to use the ones that are built on top of threads, such as executors and, until it was deprecated, AsyncTask. You can avoid it altogether by using Kotlin coroutines, which you will learn more about later in this chapter.

In the next section, you will explore callbacks, another approach to asynchronous Android programming.

Callbacks

Another common approach to asynchronous programming in Android is using callbacks. A callback is a function that will be run when the asynchronous code has finished executing. Some libraries offer callback functions that developers can use in their projects.

The following is a simple example of a callback:

private fun fetchTextWithCallback() {
  fetchTextWithCallback { text ->
    //display text
    displayText(text)
    }
}
fun fetchTextWithCallback(onSuccess: (String) -> Unit) {    
     Thread {
          val text = getTextFromNetwork()    
          onSuccess(text)
    }.start()
}

In the preceding example, after fetching the text in the background, the onSuccess callback will be called and will display the text on the UI thread.

Callbacks work fine for simple asynchronous tasks. They can, however, become complicated easily, especially when nesting callback functions and handling errors. This makes it hard to read and test. You can avoid this by avoiding nesting callbacks and splitting functions into subfunctions. It is better to use coroutines, which you will learn more about shortly in this chapter.

AsyncTask

AsyncTask has been the go-to class for running background tasks in Android. It makes it easier to do background processing and post data to the main thread. With AsyncTask, you don’t have to manually handle threads.

To use AsyncTask, you have to create a subclass of it with three generic types:

AsyncTask<Params?, Progress?, Result?>()

These types are as follows:

  • Params: This is the type of input for AsyncTask or is void if there’s no input needed.
  • Progress: This argument is used to specify the progress of the background operation or Void if there’s no need to track the progress.
  • Result: This is the type of output of AsyncTask or is void if there’s no output to be displayed.

For example, if you are going to create AsyncTask to download text from a specific endpoint, your Params will be the URL (String) and Result will be the text output (String). If you want to track the percentage of time remaining to download the text, you can use Integer for Progress. Your class declaration would look like this:

class DownloadTextAsyncTask : AsyncTask<String, Integer,
 String>()

You can then start AsyncTask with the following code:

DownloadTextAsyncTask().execute("https://example.com")

AsyncTask has four events that you can override for your background processing:

  • doInBackground: This event specifies the actual task that will be run in the background, such as fetching/saving data to a remote server. This is the only event that you are required to override.
  • onPostExecute: This event specifies the tasks that will be run in the UI thread after the background operation finishes, such as displaying the result.
  • onPreExecute: This event runs on the UI thread before doing the actual task, usually displaying a progress loading indicator.
  • onProgressUpdate: This event runs in the UI thread to denote progress on the background process, such as displaying the amount of time remaining to finish the task.

The diagram in Figure 1.5 visualizes these AsyncTask events and in what threads they are run:

Figure 1.5 – AsyncTask events in main and background threads

Figure 1.5 – AsyncTask events in main and background threads

The onPreExecute, onProgressUpdate, and onPostExecute functions will run on the main thread, while doInBackground executes on the background thread.

Coming back to our example, your DownloadTextAsync class could look like the following:

class DownloadTextAsyncTask : AsyncTask<String, Void,
 String>() {
        override fun doInBackground(vararg params:
          String?): String? {
            valtext = getTextFromNetwork(params[0] ?: "")
            //get text from network
            return text
        }
        override fun onPostExecute(result: String?) {
            //Display on UI
        }
}

In DownloadTextAsync, doInBackground fetches the text from the network and returns it as a string. onPostExecute will then be called with that string that can be displayed in the UI thread.

AsyncTask can cause context leaks, missed callbacks, or crashes on configuration changes. For example, if you rotate the screen, the activity will be recreated and another AsyncTask instance can be created. The original instance won’t be automatically canceled and when it finishes and returns to onPostExecute(), the original activity is already gone.

Using AsyncTask also makes your code more complicated and less readable. As of Android 11, AsyncTask has been deprecated. It is recommended to use java.util.concurrent or Kotlin coroutines instead.

In the next section, you will explore one of the java.util.concurrent classes for asynchronous programming, Executors.

Executors

One of the classes in the java.util.concurrent package that you can use for asynchronous programming is java.util.concurrent.Executor. An executor is a high-level Java API for managing threads. It is an interface that has a single function, execute(Runnable), for performing tasks.

To create an executor, you can use the utility methods from the java.util.concurrent.Executors class. Executors.newSingleThreadExecutor() creates an executor with a single thread.

Your asynchronous code with Executor will look like the following:

val handler = Handler(Looper.getMainLooper())
private fun fetchTextWithExecutor() {
  val executor = Executors.newSingleThreadExecutor()
  executor.execute {
    // get text from network
           val text = getTextFromNetwork()
    handler.post {
      // Display on UI
    }
  }
}

The handler with Looper.getMainLooper() allows you to communicate back to the main thread so you can update the UI after your background task has been done.

ExecutorService is an executor that can do more than just execute(Runnable). One of its subclasses is ThreadPoolExecutor, an ExecutorService class that implements a thread pool that you can customize.

ExecutorService has submit(Runnable) and submit(Callable) functions, which can execute a background task. They both return a Future object that represents the result.

The Future object has two functions you can use, Future.isDone() to check whether the executor has finished the task and Future.get() to get the results of the task, as follows:

val handler = Handler(Looper.getMainLooper()
private fun fetchTextWithExecutorService() {
  val executor = Executors.newSingleThreadExecutor()
  val future = executor.submit {
     displayText(getTextFromNetwork())    
  }
  ...
  val result = future.get()
}

In the preceding code, the executor created with a new single thread executor was used to submit the runnable function to get and display text from the network. The submit function returns a Future object, which you can later use to fetch the result with Future.get().

In this section, you learned some of the methods that you can use for asynchronous programming in Android. While they do work and you can still use them (except for the now-deprecated AsyncTask), nowadays, they are not the best method to use moving forward.

In the next section, you will learn the new, recommended way of asynchronous programming in Android: using Kotlin coroutines and flows.

The new way to do it – coroutines and flows

In this section, you will learn about the recommended approach for Android asynchronous programming: using coroutines and flows. Coroutines is a Kotlin library you can use in Android to perform asynchronous tasks. Coroutines is a library for managing background tasks that return a single value. Flows are built on top of coroutines that can return multiple values.

Kotlin coroutines

Coroutines is a Kotlin library for managing background tasks, such as making network calls and accessing files or databases, or performing long-running background tasks. Using Kotlin coroutines is Google’s official recommendation for asynchronous programming on Android. Their Android Jetpack libraries, such as Lifecycle, WorkManager, and Room-KTX, now include support for coroutines. Other Android libraries, such as Retrofit, Ktor, and Coil, provide first-class support for Kotlin coroutines.

With Kotlin coroutines, you can write your code in a sequential way. A long-running task can be made into a suspend function. A suspend function is a function that can perform its task by suspending the thread without blocking it, so the thread can still run other tasks. When the suspending function is done, the current thread will resume execution. This makes the code easier to read, debug, and test. Coroutines follow a principle of structured concurrency.

You can add coroutines to your Android project by adding the following lines to your app/build.gradle file dependencies:

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-
  core:1.6.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-
  android:1.6.0"

kotlinx-coroutines-core is the main library for Kotlin coroutines, while kotlinx-coroutines-android adds support for the main Android thread (Dispatchers.Main).

To mark a function as a suspending function, you can add the suspend keyword to it; for example, here we have a function that calls the fetchText() function, which retrieves text from an endpoint and then displays it in the UI thread:

fun fetchText(): String {
  ...
}

You can make the fetchText() function a suspending function by prefixing the suspend keyword, as follows:

suspend fun fetchText(): String { ... }

Then, you can create a coroutine that will call the fetchText() suspending function and display the list, as follows:

lifecycleScope.launch(Dispatchers.IO) {
    val fetchedText = fetchText()  
    withContext(Dispatchers.Main) {
      displayText(fetchedText)
    }
}

lifecycleScope is the scope with which the coroutine will run. launch creates a coroutine to run in Dispatchers.IO, which is a thread for I/O or network operations.

The fetchText() function will suspend the coroutine before it starts the network request. While the coroutine is suspended, the main thread can do other work.

After getting the text, it will resume the coroutine. withContext(Dispatchers.Main) will switch the coroutine context to the main thread, where the displayText(text) function will be executed (Dispatchers.Main).

In Android Studio, the Editor window identifies the suspend function calls in your code with a gutter icon next to the line number. As shown in lines 13 and 15 in Figure 1.6, the fetchText() and withContext() lines have the suspend function call gutter icon:

Figure 1.6 – Android Studio suspend function call gutter icon

Figure 1.6 – Android Studio suspend function call gutter icon

You can learn more about Kotlin coroutines in Chapter 2, Understanding Kotlin Coroutines.

In the next section, you will learn about Kotlin Flows, built on top of coroutines, which can return multiple sequences of values.

Kotlin Flows

Flow is a new Kotlin asynchronous stream library that is built on top of Kotlin coroutines. A flow can emit multiple values instead of a single value and over a period of time. Kotlin Flow is ideal to use when you need to return multiple values asynchronously, such as automatic updates from your data source.

Flow is now used in Jetpack libraries such as Room-KTX and Android developers are already using Flow in their applications.

To use Kotlin Flows in your Android project, you have to add coroutines. An easy way to create a flow of objects is to use the flow{} builder. With the flow{} builder function, you can add values to the stream by calling emit.

Let’s say in your Android app you have a getTextFromNetwork function that fetches text from a network endpoint and returns it as a String object:

fun getTextFromNetwork(): String { ... }

If we want to create a flow of each word of the text, we can do it with the following code:

private fun getWords(): Flow<String> = flow {
  getTextFromNetwork().split(" ").forEach {
    delay(1_000)
    emit(it)
  }
}

Flow does not run or emit values until the flow is collected with any terminal operators, such as collect, launchIn, or single. You can use the collect() function to start the flow and process each value, as follows:

private suspend fun displayWords() {
          getWords().collect {
          Log.d("flow", it)
           }
}

A visual representation of this flow is shown in the following figure:

Figure 1.7 – Kotlin Flow visual representation

Figure 1.7 – Kotlin Flow visual representation

As you can see in Figure 1.7, as soon as the getWords() flow emits a string, the displayWords function collects the string and displays it immediately on the logs.

You will learn more about Kotlin Flows in Chapter 5, Using Kotlin Flows.

In this section, you learned about Kotlin coroutines and flows, the recommended way to carry out asynchronous programming in Android. Coroutines is a Kotlin library for managing long-running tasks in the background. Flow is a new Kotlin asynchronous stream library, built on top of coroutines, that can emit multiple values over a period of time.

Summary

In this chapter, you revisited the concept of asynchronous programming. We learned that asynchronous programming helps you execute long-running tasks in the background without freezing the app and annoying your users.

You then learned about various ways you can do asynchronous programming in Android, including with threads, AsyncTask, and Executors. We also learned that they allow you to perform tasks in the background and update the main thread. AsyncTask is already deprecated, and threads and Executors are not the best ways to carry out asynchronous programming in Android.

Finally, you were introduced to the new, recommended way to carry out asynchronous programming in Android: with Kotlin’s Coroutines and Flow. We learned that Coroutines is a Kotlin library that you can use to easily perform asynchronous, non-blocking, and long-running tasks in the background. Flow, built on top of Coroutines, allows you to handle functions that return multiple values over time.

In the next chapter, you will dive deeper into Kotlin coroutines and learn how to use them in your Android project.

Further reading

This book assumes that you have experience and skills in Android development with Kotlin. If you would like to learn more about this, you can read the book How to Build Android Apps with Kotlin (Packt Publishing, 2021, ISBN 9781838984113).

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Find out how to improve app performance with Kotlin coroutines
  • Discover the new recommended ways to use Kotlin coroutines and flows
  • Learn the basics of asynchronous programming, along with an overview of coroutines and flow

Description

Coroutines and flows are the new recommended way for developers to carry out asynchronous programming in Android using simple, modern, and testable code. This book will teach you how coroutines and flows work and how to use them in building Android applications, along with helping you to develop modern Android applications with asynchronous programming using real data. The book begins by showing you how to create and handle Kotlin coroutines on Android. You’ll explore asynchronous programming in Kotlin, and understand how to test Kotlin coroutines. Next, you'll learn about Kotlin flows on Android, and have a closer look at using Kotlin flows by getting to grips with handling flow cancellations and exceptions and testing the flows. By the end of this book, you'll have the skills you need to build high-quality and maintainable Android applications using coroutines and flows.

Who is this book for?

This book is for intermediate-level Android developers who want to level up their Android app-building skills. Familiarity with Android development and basic knowledge of Kotlin are needed to make the most of this book.

What you will learn

  • Understand how coroutines and flows differ from existing ways
  • Apply asynchronous programming in Android with coroutines and flows
  • Find out how to build your own coroutines and flows in Android
  • Handle, manipulate, and combine data in coroutines and flows
  • Handle cancellations and exceptions from coroutines and flows
  • Discover how to add tests for your coroutines and flows
  • Integrate coroutines and flows into your Android projects

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jul 27, 2022
Length: 164 pages
Edition : 1st
Language : English
ISBN-13 : 9781801817202
Vendor :
Google
Category :
Languages :
Tools :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning

Product Details

Publication date : Jul 27, 2022
Length: 164 pages
Edition : 1st
Language : English
ISBN-13 : 9781801817202
Vendor :
Google
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 127.97
Kickstart Modern Android Development with Jetpack and Kotlin
$46.99
Android UI Development with Jetpack Compose
$49.99
Simplifying Android Development with Coroutines and Flows
$30.99
Total $ 127.97 Stars icon

Table of Contents

10 Chapters
Part 1 – Kotlin Coroutines on Android Chevron down icon Chevron up icon
Chapter 1: Introduction to Asynchronous Programming in Android Chevron down icon Chevron up icon
Chapter 2: Understanding Kotlin Coroutines Chevron down icon Chevron up icon
Chapter 3: Handling Coroutine Cancelations and Exceptions Chevron down icon Chevron up icon
Chapter 4: Testing Kotlin Coroutines Chevron down icon Chevron up icon
Part 2 – Kotlin Flows on Android Chevron down icon Chevron up icon
Chapter 5: Using Kotlin Flows Chevron down icon Chevron up icon
Chapter 6: Handling Flow Cancelations and Exceptions Chevron down icon Chevron up icon
Chapter 7: Testing Kotlin Flows Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Full star icon Full star icon 5
(2 Ratings)
5 star 100%
4 star 0%
3 star 0%
2 star 0%
1 star 0%
Alexander Forrester Oct 17, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book will have you up and running harnessing the benefits of using Coroutines and Flows in your apps straight away. It packs a lot in with a brief introduction to asynchronous programming before covering both in-depth. This includes handling exceptions, cancellations and testing. The chapters finish with exercises to make it stick. I particularly liked the Flows section which excels in teaching how to use them in a clear way. Overall, highly recommended.
Amazon Verified review Amazon
Tiny Aug 23, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Need help with Android coroutines to shorten demands on the main thread and reduce error? “Simplifying Android Development with Coroutines and Flows” Packt, by Jomar Tigcal is a simple work to introduce or refresh skills in this area. Android’s predominance on mobile devices means managing the amount of computing resources is always of critical importance. This work first covers the importance of coroutines for asynchronous work and then demonstrates flows when one needs the code to emit multiple values at the same time. A useful reference if spending any amount of time on Android programming. The book only has two sections, one on coroutines and one on flows. The sections mirror each other by describing first how to build the code, then catching cancellations and exceptions, and finally, testing the code for success. The building code sections are well-documented with clear examples. All examples are built around a sample code for calling movie titles from an existing database. Once capable of writing the code, the next step is finding ways to make sure the code continues running successfully. Included are ways to find the exceptions, stop at a pre-defined time, or filter for various values. The advantage here of flows over coroutines is that flows can manage multiple data inputs and filter over a wider range, such as being able to select only the most popular movies rather than the one-to-n listing. The final component, of course, for any code is being able to test. The author includes several test samples to either manually build into the code or use JUnit4 to automate across multiple code samples. Understanding how to test is a key element of knowing how code works, and how to build better code to accomplish goals. Overall, an excellent short reference to one component of Android code. Useful to those coding Android now, or looking to in the near future. The one lack is detailed case studies offering examples of where to go when one moves past the basics. However, the code language and samples are more than sufficient to drive that train on your own.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.