как использовать значения из сопрограмм вне сопрограмм - PullRequest
0 голосов
/ 09 июля 2020

Как мне использовать ответ из базы данных комнаты вне сопрограммы, из которой он был вызван

Мне нужно использовать сопрограммы для выполнения запроса из базы данных комнаты, а затем отображать эти данные в рециклервью . Проблема, с которой я столкнулся, заключается в том, что я не могу получить ответ из базы данных для отображения за пределами сопрограммы.

мой код.

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

Я также не могу поставить код recyclerview в сопрограмме, потому что он говорит, что вы не можете коснуться иерархии представления.

Ответы [ 2 ]

1 голос
/ 09 июля 2020

В Activity или Fragment вы можете использовать lifecycleScope для запуска сопрограммы, по умолчанию она работает в контексте сопрограммы Main, поэтому вы можете обновить свой пользовательский интерфейс оттуда:

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

Чтобы использовать lifecycleScope, добавьте следующую строку к зависимостям файла build.gradle приложения:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-alpha05"
0 голосов
/ 09 июля 2020

Вы можете использовать переменную respo как глобальную переменную класса, а затем использовать свойство withContext (Dispatcher.main), чтобы использовать основной поток и ждать результата. Примерно так:

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