Android Kotlin使用工作线程的协程来等待&;从UI线程获取一些东西

Android Kotlin使用工作线程的协程来等待&;从UI线程获取一些东西,android,multithreading,kotlin,kotlin-coroutines,Android,Multithreading,Kotlin,Kotlin Coroutines,假设您在一个WorkerThread中执行一个长时间运行的任务。但是,为了完成上述长时间运行的任务,您必须从UI线程中获取一些信息 基本上,我需要访问UI线程,该线程将生成一个对象,该对象必须在UI线程上初始化,然后可以在任何线程中使用 我想做的可能是使用协同路由/挂起函数,其中工作线程实际等待UI线程上的操作完成 我怎样才能做到这一点呢?谢谢 以下是我打算实现的目标: @WorkerThread fun processTask() { // ... do some stuff to i

假设您在一个
WorkerThread
中执行一个长时间运行的任务。但是,为了完成上述长时间运行的任务,您必须从
UI线程
中获取一些信息

基本上,我需要访问UI线程,该线程将生成一个对象,该对象必须在UI线程上初始化,然后可以在任何线程中使用

我想做的可能是使用协同路由/挂起函数,其中工作线程实际等待UI线程上的操作完成

我怎样才能做到这一点呢?谢谢

以下是我打算实现的目标:

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


我希望这会有所帮助。

您可以尝试以下方法:

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
            }

您可以尝试以下方法:

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
            }

使用
Dispatchers.Main
Dispatchers.IO
可能允许您使用不同的上下文,但我们需要了解启动新的协同程序并不等同于启动新线程。协程是轻量级线程。对于通信,您需要使用一些称为
频道的概念。请参考这个


类似地,使用通道,您可以使用
Dispatchers.Main
Dispatchers.IO
将线程中的协同路由链接到另一个线程上的协同路由,这可能允许您使用不同的上下文,但我们需要了解,启动新协同路由并不等同于启动新线程。协程是轻量级线程。对于通信,您需要使用一些称为
频道的概念。请参考这个


类似地,使用通道,您可以将线程中的一个协程链接到另一个线程上的协程

只需在类中实现协程作用域,并将类中的变量定义为

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

}

只需在类中实现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
    }
}

}

谢谢差不多就是这样。我已编辑我的问题以添加模式。我的约束条件是,我在一个工作线程上调用的方法中。而不是相反。有了这个解决方案,我们如何在两个协同程序之间进行通信?我们如何在两个协同路由之间发送和接收消息。它只是在第一个协同程序中使用其他协同程序的上下文来执行这段代码。实际上,我认为@mr patel做得对,因为我设法用
GlobalScope.async(…).wait()
创建了我的
getSomethingFromUiThread
,但调用此方法的方法也必须是可挂起的。但我不能这样做,我正在重写父类中的方法。所以不管怎样,我认为他的答案是正确的。一旦我让它工作起来,我会验证它。除非有一种真正的阻塞方法?但是,这不再是关于合作项目了…谢谢!差不多就是这样。我已编辑我的问题以添加模式。我的约束条件是,我在一个工作线程上调用的方法中。而不是相反。有了这个解决方案,我们如何在两个协同程序之间进行通信?我们如何在两个协同路由之间发送和接收消息。它只是在第一个协同程序中使用其他协同程序的上下文来执行这段代码。实际上,我认为@mr patel做得对,因为我设法用
GlobalScope.async(…).wait()
创建了我的
getSomethingFromUiThread
,但调用此方法的方法也必须是可挂起的。但我不能这样做,我正在重写父类中的方法。所以不管怎样,我认为他的答案是正确的。一旦我让它工作起来,我会验证它。除非有一种真正的阻塞方法?但是,这不再是关于合作计划。。。