I have a suspend
function that calls POST request to the server. I want to configure some text in the activity to show the information I received from the server.
suspend fun retrieveInfo():String
I tried calling inside onCreate
, onResume
but crashes runtime.
runBlocking {
retrieveInfo()
}
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.augmentedimage/com.google.AugmentedImageActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3086)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3229)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
Where am I suppose to put these suspend calls (in which part of lifecycle of activity)? Should I be using something other than runBlocking
?
Java Thread suspend() methodThe suspend() method of thread class puts the thread from running to waiting state. This method is used if you want to stop the thread execution and start it again when a certain event occurs. This method allows a thread to temporarily cease execution.
SUSPENDING: Function A, while has started, could be suspended, and let Function B execute, then only resume later. The thread is not locked by Function A. In short, the suspend function is a function that could be started, paused and resume, (and pause and resume…. if wanted repeatedly) and then end.
A suspending function is simply a function that can be paused and resumed at a later time. They can execute a long running operation and wait for it to complete without blocking.
Suspend function should be called only from a coroutine. That means to call a suspend function you need to use a coroutine builder, e.g. launch , async or runBlocking (recommended to use only in unit tests).
By default runBlocking
runs the suspending code block
in the thread runBlocking
was called on.
So if you called runBlocking
from the Activity
callback your suspending block will be executed on the main thread, from which you cannot access network (query a server).
You need to switch a dispatcher in your coroutine block for that call. The simplest fix for your code would be to move the execution to the Dispatchers.IO
.
runBlocking {
withContext(Dispatchers.IO) {
retrieveInfo()
}
}
That being said, I suggest two things (not related directly to your question):
Coroutines on Android
(this part and the following ones)2. Don't use runBlocking
for your case, but define a correct job
and use job.launch{}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With