Reputation: 31
How do I use the response from a room database outside of the coroutine it was called from
I need to use coroutines to execute a request from a room database, then take this data display it in a recyclerview. The problem I'm having is that I can't get the response from the database to show up outside of the coroutine.
my code.
class seconddisplay : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.second_display)
GlobalScope.launch {
val respo = second_Database.getInstance(context = this@seconddisplay).DAO().seeAllcodes()
}
second_recyclerview.apply {
layoutManager = LinearLayoutManager(this@seconddisplay)
adapter = displayAdapter(respo)
}
}
I also can't put the recyclerview code within the coroutine because it says you can't touch the hierarchy of the view.
Upvotes: 1
Views: 2205
Reputation: 585
You could use the respo variable as a global variable of the class.And then use the property withContext(Dispatcher.main) to use the mainthread and wait for the result.Something like this:
private var respo: YourDataType? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.second_display)
getRespo()
}
private fun getRespo(){
val supervisorJob = SupervisorJob()
val coroutineScope = CoroutineScope(Dispatchers.IO + supervisorJob)
coroutineScope.launch {
withContext(Dispatchers.Main) {
respo = second_Database.getInstance(this@seconddisplay).DAO().seeAllcodes()
second_recyclerview.apply {
layoutManager = LinearLayoutManager(this@seconddisplay)
if(respo!=null){
adapter = displayAdapter(respo)
}else{//handle respo being null, maybe show a message
}
}
}
}
}
Upvotes: -1
Reputation: 30645
In Activity
or Fragment
you can use lifecycleScope
to launch a coroutine, by default it runs on the Main
coroutine context, therefore you can update your UI from there:
lifecycleScope.launch {
// call like this if `seeAllcodes()` method is suspend
val respo = second_Database.getInstance(context = this@seconddisplay).DAO().seeAllcodes()
// call like this if `seeAllcodes()` method isn't suspend
val respo = withContext(Dispatchers.IO) { // runs on background thread
second_Database.getInstance(context = this@seconddisplay).DAO().seeAllcodes()
}
// update UI
second_recyclerview.apply {
layoutManager = LinearLayoutManager(this@seconddisplay)
if (respo != null) {
adapter = displayAdapter(respo)
}
}
}
To use lifecycleScope
add next line to dependencies of the app's build.gradle file:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-alpha05"
Upvotes: 2