Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and how to call suspend function from Android Activity?

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?

like image 351
user3087615 Avatar asked Jul 06 '19 09:07

user3087615


People also ask

Can we call suspend function from Java?

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.

What is a suspend function Android?

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.

What is the use of Suspend function?

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.

Should be called only from a coroutine or another suspend function?

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).


1 Answers

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):

  1. Read 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{}

like image 100
Bartek Lipinski Avatar answered Nov 08 '22 12:11

Bartek Lipinski