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
Both launch
and async
are used to start a coroutine, but they serve different purposes and have different return types. Here's a detailed comparison:
launch: It's used when there's an asynchronous task that doesn't need to return a result. It just executes the coroutine without blocking the current thread.
async: It's used when you need to compute a result asynchronously and return it. It returns a Deferred<T>
, where T
is the type of the result.
launch: Returns a Job
that represents the coroutine. It doesn't produce a result. You can use the Job
to manage the lifecycle of the coroutine, for example, to cancel it.
async: Returns a Deferred<T>
. This is a type of Job
that can also hold a result or an exception. You can use the await()
function on a Deferred
object to get the result (or throw an exception if the coroutine failed).
With launch:
val job: Job = GlobalScope.launch { // Some asynchronous work } // Optional: if you want to cancel the coroutine job.cancel()
With async:
val deferred: Deferred<ResultType> = GlobalScope.async { // Some asynchronous computation return@async computedValue } // When you need the result val result: ResultType = deferred.await()
launch: Any exception thrown inside the launch
coroutine builder will propagate to its parent coroutine or the default exception handler (if there's no parent). You usually handle exceptions inside the coroutine using a try/catch block.
async: If there's an exception, it gets stored in the Deferred
object. When you call await()
, either the result is returned, or the stored exception is thrown.
launch: When you need to fire-and-forget, like updating UI components without expecting a result.
async: When you want to fetch or compute something in the background and use the result later. It's often used in combination with other asynchronous tasks. For example, if you want to fetch data from multiple network sources concurrently, you can use multiple async
blocks and then gather the results.
The decision to use launch
vs. async
depends on what you intend to do:
For tasks that don't need to return a result, use launch
.
For tasks that compute something and you need the result, use async
.
In practice, while both are crucial, misuse of async
(especially without a reason to gather results) can be considered an anti-pattern, as it can introduce unnecessary complexities. Always choose the right tool for the task at hand.
CoroutineContext in launch and async Kotlin Coroutines:
launch
and async
can take a CoroutineContext
as a parameter, allowing you to specify the execution context.Dispatchers.IO
for network-related tasks or Dispatchers.Main
for UI-related tasks.// Using launch with CoroutineContext GlobalScope.launch(Dispatchers.IO) { // Background task } // Using async with CoroutineContext val deferredResult = GlobalScope.async(Dispatchers.Default) { // Concurrent task with a result }