Kotlin использует сопрограммы из рабочего потока для ожидания и получения чего-либо из пользовательского интерфейса - PullRequest
1 голос
/ 25 сентября 2019

Допустим, вы в WorkerThread выполняете долгосрочное задание.Но, чтобы завершить эту долгосрочную задачу, вы должны получить что-то из UI Thread.

. В основном мне нужен доступ к UI Thread , которыйсгенерирует объект, который ДОЛЖЕН быть инициализирован в потоке пользовательского интерфейса, но затем может использоваться в любом потоке.

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

Как мне этого добиться?Спасибо!

Ниже представлена ​​схема того, чего я намерен достичь:

@WorkerThread
fun processTask() {
    // ... do some stuff to init work
    val something = getSomethingFromUiThread() // wait
    // ... resume & complete stuff with "something"
}

@MainThread
suspend fun getSomethingFromUiThread() {
    // ... create object on UI Thread
    // ... return initialized object to the worker thread
}

Надеюсь, это поможет.

Ответы [ 3 ]

3 голосов
/ 25 сентября 2019

Вы можете попробовать что-то вроде этого:

GlobalScope.launch(Dispatchers.Main) { //Your Main UI Thread
              val myuithreadobject = myobject()
               withContext(Dispatchers.IO) {
               //this is out background thread
                        nodelist = ArrayList()
                       val info = myuithreadobject

                       printAllViews(info)

                    }
              //after background thread is finished
        //do work on main thread
            }
0 голосов
/ 25 сентября 2019

Просто внедрите CoroutineScope в своем классе и определите переменную в своем классе как

 private val job = Job()
 override val coroutineContext: CoroutineContext
 get() = job + Dispatchers.Main

, и теперь вы можете делать то же самое в своем классе: -

launch(Dispatchers.Main) {
    val data = async(Dispatchers.IO) {
        // do your work in background thread
    }.await()
    //And now data return on UI thread
}

Пример: -

    Class MyClassFragment: Fragment(), CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
    get() = job + Dispatchers.Main

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    launch(Dispatchers.Main) {
        val data = async(Dispatchers.IO) {
            // do your background operation
        }.await()
        //And now data return on UI thread
    }
}

}
0 голосов
/ 25 сентября 2019

Использование Dispatchers.Main и Dispatchers.IO может позволить вам использовать разные контексты, но мы должны понимать, что запуск новой сопрограммы - это не запуск нового потока.Сопрограммы легкие нити.А для общения нужно использовать некое понятие, называемое Channels.Пожалуйста, обратитесь по этой ссылке .

Аналогично, используя каналы, вы можете связать сопрограмму в потоке с сопрограммой в другом

...