When starting with Kotlin on Android, the first thing I needed to do was to fetch data over the internet. I knew that coroutines provide a built-in way for asynchronous work (no need for AsyncTask or RxJava!), but how do I define my network call interfaces?
The wrong way: Async-style functions
You might think that you need something that you can call from anywhere and just doesn't block the main thread. Googling and StackOverflowing around, you might end up with this easy (but wrong) solution.
Awesome, right? You use
Dispatchers.IO so you are not blocking the main thread. And you can call this from anywhere.
GlocalScrope is an anti-pattern in Kotlin and not recommended for various reasons (e.g. not bound to any job and will continue running even if not needed).
The recommended way: Structured concurrency with async
The ideal way is to create coroutines and use them inside
ContextScopes that are bounded to the lifecycle of a "parent" element (e.g. your
ViewModel). With this approach, the active coroutines will be cancelled when they are not needed anymore (e.g. when the user navigates to another screen). Also, you make sure that you don't have common memory leaks (e.g. network calls that hanged and no one stopped them) in your app.
A common use case is to make multiple network calls before processing/combining your results to something the user can see. If you just call
suspend functions one after the other they will be executed sequentially.
To run them in parallel, use the
async coroutine builder. Execution starts as soon as the
async block is defined.
The experimental way: Flows
If you need to do complicated compositions of the results, returning the result as a Flow might be suitable. Flows allow you the flexibility to compose and transform the return results in a fluent way.
Didn't try it yet in a project of mine, but seems like a promising approach.
Happy network calling!