Permissions Contact permissions? Loading Show Retry Dialog retry? yes no Network Error success Canceled Granted? Read Contacts Show Results yes no yes no
to read and maintain - Callbacks - Callback hell, hard to refactor, no cancellation - Promises / Futures - CompletableFuture minSdk 24, no cancellation, concurrent by default - Observables / Reactive Streams - Steep learning curve, different paradigm, too many operators
finalized - Guaranteed backwards compatibility - Calls covered here are unlikely to change - IDE tools to ease migration Can I use it in production? “Yes! You should.” - Roman Elizarov (seconded by me)
{ cont -> // this code gets executed immediately to set up the coroutine Thread { Thread.sleep(1000) // some time later, use the continuation to resume from suspension try { val result = i.toInt() cont.resume(result) }catch (e: NumberFormatException) { cont.resumeWithException(e) } }.start() // after leaving this method, the caller will suspend until resume is called } }
way: What thread picks back up after a suspension resumes. - UI - CommonPool - newSingleThreadContext(name = "single") - newFixedThreadPoolContext(nThreads = 3, name = "pool")
1 } // one is a Promise (Deferred<Int>). It has already started val two = async(CommonPool) { delay(100) return@async 2 } // now both promises are running // await() suspends until the promise resolves val sum = one.await() + two.await()
{ dangerousMethod() // throws CancellationException } catch (e: CancellationException){ throw e // rethrow, to be handled by the coroutine context } catch (e: Exception) { Log.w("EXAMPLE", "dangerous method exploded") } doTheNextThing() // next thing won't get called anymore } job.cancel()