Why does `GlobalScope.launch(Dispatchers.Main)` th...
# announcements
b
Why does
GlobalScope.launch(Dispatchers.Main)
throw a
Fatal Exception: android.os.NetworkOnMainThreadException
and
GlobalScope.async
doesn't?
j
How about
CoroutineScope(Dispatchers.Main).launch
? See here: https://codelabs.developers.google.com/codelabs/kotlin-coroutines/#0
g
b
What does "You MUST NOT forget about the coroutine you’ve started with async." mean?
g
It means exactly this
b
Specifically "forget".
g
if nobody never call
await()
you will never know about this error
it actually explained in comments to this answer
Can you elaborate on “You MUST NOT forget about the coroutine you’ve started with async”? Are there gotchas that one wouldn’t expect for example?
An uncaught exception inside the async code is stored inside the resulting Deferred and is not delivered anywhere else, it will get silently dropped unless processed.
If you forget the result of async than it will finish and will be garbage collected. However, if it crashes due to some bug in your code, you’ll never learn about that. That is why
b
Do they mean like this?
Copy code
val addJob = GlobalScope.async {
    val hostAddress: String
    val ip = InetAddress.getByName(hostName)

    hostAddress = ip.hostAddress

    addIPToMap(hostAddress)
}

runBlocking {
    addJob.join()
}
g
yes, this is an example when you never handle error and do not know that your code is probably broken
b
How could I make it better?
g
If you don’t need result, use
launch
if you need result from async, use
.await()
instaed of join, to handle result or errors
b
simple smile I see
g
And in case of
launch
you should wrap code to try/catch or
runCatching
and handle result of operation, otherwise in case of error you application will crash
Returning to your original problem,
NetworkOnMainThreadException
happens there because you do network requesst (lookup ip address) on the main thread, to avoid this use
<http://Dispatchers.IO|Dispatchers.IO>