More Related Content Similar to Kotlin Coroutines: Let it async in (20) Kotlin Coroutines: Let it async in1. Kotlin Coroutines:
Let it async in
Bapusaheb Patil
Google Certified Android Developer,
IDF Certified UX Designer
www.bapspatil.com
42. val job = launch {
doLongTask()
}
job.join() If you need to suspend the coroutine
job.cancel()
Job
bapspatil.com
45. val deferred = async {
doLongTask()
}
val result = deferred.await()
deferred.cancel()
Deferred<String>
bapspatil.com
49. suspend fun fetchMovieData() {
val popularMovies = apiService.getMoviesByType(“POPULAR”)
val topRatedMovies = apiService.getMoviesByType(“TOP_RATED”)
val upcomingMovies = apiService.getMoviesByType(“UPCOMING”)
val nowPlayingMovies = apiService.getMoviesByType(“NOW_PLAYING”)
val allMovies = mergeAllMovies(popularMovies, topRatedMovies,
upcomingMovies, nowPlayingMovies)
database.saveToDb(allMovies)
}
Takes 4.8 seconds
bapspatil.com
50. suspend fun fetchMovieData() {
val popularDeferred = async { apiService.getMoviesByType(“POPULAR”) }
val topRatedDeferred = async { apiService.getMoviesByType(“TOP_RATED”) }
val upcomingDeferred = async { apiService.getMoviesByType(“UPCOMING”) }
val nowPlayingDeferred = async { apiService.getMoviesByType(“NOW_PLAYING”) }
val popularMovies = popularDeferred.await()
val topRatedMovies = topRatedDeferred.await()
val upcomingMovies = upcomingDeferred.await()
val nowPlayingMovies = nowPlayingDeferred.await()
val allMovies = mergeAllMovies(popularMovies, topRatedMovies, upcomingMovies,
nowPlayingMovies)
database.saveToDb(allMovies)
}
bapspatil.com
51. suspend fun fetchMovieData() {
val popularDeferred = async { apiService.getMoviesByType(“POPULAR”) }
val topRatedDeferred = async { apiService.getMoviesByType(“TOP_RATED”) }
val upcomingDeferred = async { apiService.getMoviesByType(“UPCOMING”) }
val nowPlayingDeferred = async { apiService.getMoviesByType(“NOW_PLAYING”) }
val allMovies = mergeAllMovies(popularDeferred.await(), topRatedDeferred.await(),
upcomingDeferred.await(), nowPlayingDeferred.await())
database.saveToDb(allMovies)
}
Takes 2.6 seconds
bapspatil.com
52. suspend fun fetchMovieData() {
val popularDeferred = async { apiService.getMoviesByType(“POPULAR”) }
val topRatedDeferred = async { apiService.getMoviesByType(“TOP_RATED”) }
val upcomingDeferred = async { apiService.getMoviesByType(“UPCOMING”) }
val nowPlayingDeferred = async { apiService.getMoviesByType(“NOW_PLAYING”) }
val allMovies = mergeAllMovies(popularDeferred.await(), topRatedDeferred.await(),
upcomingDeferred.await(), nowPlayingDeferred.await())
database.saveToDb(allMovies)
// Update the UI from the suspending function
runOnUiThread { updateUI(allMovies) }
}
Updating the UI...
bapspatil.com
56. class MyActivity : AppCompatActivity() {
private val compositeDisposable = CompositeDisposable()
override fun onCreate() {
// ...
compositeDisposable.add(getFirstObservable())
compositeDisposable.add(getSecondObservable())
}
override fun onDestroy() {
super.onDestroy()
compositeDisposable.clear()
}
}
bapspatil.com
57. class MyActivity : AppCompatActivity() {
private var firstJob: Job? = null
private var secondJob: Job? = null
override fun onCreate() {
// ...
firstJob = launch {
doSomeWork()
}
secondJob = launch {
doSomeMoreWork()
}
}
override fun onDestroy() {
super.onDestroy()
firstJob.cancel()
secondJob.cancel()
}
} bapspatil.com
60. class MyActivity : AppCompatActivity() {
lateinit var activityJob: Job
override fun onCreate() {
activityJob = Job()
val outerJob = launch(parent = activityJob) {
val firstJob = launch {
doSomeWork()
}
val secondJob = launch {
doSomeMoreWork()
}
}
}
override fun onDestroy() {
super.onDestroy()
activityJob.cancel()
}
}
bapspatil.com
61. val outerJob = launch(parent = activityJob) {
val firstJob = launch {
doSomeWork()
}
val secondJob = launch {
doSomeMoreWork()
}
}
● outerJob gets canceled.
● firstJob & secondJob do not!
bapspatil.com
62. val outerJob = launch(parent = activityJob) {
val firstJob = launch {
doSomeWork()
}
val secondJob = launch {
doSomeMoreWork()
}
}
bapspatil.com
63. val outerJob = launch(parent = activityJob) {
val firstJob = launch(parent = activityJob) {
doSomeWork()
}
val secondJob = launch(parent = activityJob) {
doSomeMoreWork()
}
}
bapspatil.com
69. class MyActivity : AppCompatActivity(), CoroutineScope {
lateinit var activityJob: Job
override val coroutineContext: CoroutineContext
get() = activityJob + Dispatchers.Main
override fun onCreate() {
// ...
activityJob = Job()
val outerJob = this.launch(context = coroutineContext) {
val firstJob = launch {
doSomeWork()
}
val secondJob = launch {
doSomeMoreWork()
}
}
}
override fun onDestroy() {
super.onDestroy()
activityJob.cancel()
}
}
bapspatil.com
70. launch(context = coroutineContext)
● Restricts the scope of the coroutine to
Activity’s lifecycle.
● Cancels all nested coroutines if parent
coroutine is canceled.
bapspatil.com
75. val result = withContext(IO) {
doLongTask()
}
bapspatil.com
78. bapspatil.com
suspend fun getFullMovieData(id: Int): Single<FullMovieData> {
val movieData = moviesRepo.getMovieData(id).subscribeOn(Schedulers.io)
val castData = moviesRepo.getCastData(id).subscribeOn(Schedulers.io)
return Single.zip(movieData, castData, BiFunction { movieData, castData ->
FullMovieData(movieData, castData)
})
}
79. bapspatil.com
suspend fun getFullMovieData(id: Int): FullMovieData {
id.let {
val movieData = async { moviesRepo.getMovieData(it) }
val castData = async { moviesRepo.getCastData(it) }
return FullMovieData(movieData.await(), castData.await())
}
return FullMovieData()
}
80. bapspatil.com
suspend fun getMovieTitle(query: String?): Single<String> {
return moviesRepo.searchForMovies(query).map { movieResults ->
if(movieResults.isNotEmpty() && movieResults[0].title != null) {
movieResults[0].title
} else {
errorString
}
}
}
81. bapspatil.com
suspend fun getMovieTitle(query: String?): String? {
query?.let {
val movieResults = withContext(IO) { moviesRepo.searchForMovies(it) }
val movieTitle = movieResults?.getOrNull(0)?.title
return movieTitle ?: errorString
}
return “”
}