Android如何以优雅的方式组织协同程序?

问题描述 投票:0回答:1

以优雅的方式组织协同应用程序的最佳方法是什么?我明白,问题似乎很奇怪。让我展示执行者的例子

创建一个对象AppExecutors.kt

object AppExecutors {

    private val main: Executor = MainThreadExecutor()
    private val util: Executor = Executors.newFixedThreadPool(3)

    fun main(f: () -> Unit) {
        main.execute(f)
    }

    fun util(f: () -> Unit) {
        util.execute(f)
    }

    class MainThreadExecutor : Executor {
        private val mainThreadHandler = Handler(Looper.getMainLooper())
        override fun execute(command: Runnable?) {
            mainThreadHandler.post(command)
        }
    }
}

现在,我们可以使用它。简单,最小的代码等

val exe = AppExecutors
exe.util {
    val first = calculateFirst()
    val second = calculateSecond()
    val str = ("first = $first | second = $second")
    exe.main {
        Toast.makeText(activity, "Executors $str", Toast.LENGTH_LONG).show()
    }
}

现在,我试图在协同程序AppCoRoutines.kt上使用这种方法

object AppCoRoutines{
    private val uiContext: CoroutineContext = Dispatchers.Main
    private val ioContext: CoroutineContext = Dispatchers.IO
    private val networkContext: CoroutineContext = Executors.newFixedThreadPool(3).asCoroutineDispatcher()
    private val singleContext: CoroutineContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()

    val ui: CoroutineScope = CoroutineScope(uiContext)
    val io: CoroutineScope = CoroutineScope(ioContext)
    val net: CoroutineScope = CoroutineScope(networkContext)
    val single: CoroutineScope = CoroutineScope(singleContext)
}

现在,使用这个:

val coRout = AppCoRoutines
coRout.ui.launch {
    val str: String = withContext(coRout.net.coroutineContext){
        val first = async { calculateFirst() }
        val second = async { calculateSecond() }
        ("first = $first | second = $second")
    }
    Toast.makeText(activity, "CoRoutine $str", Toast.LENGTH_LONG).show()
}

没有那么优雅。也许有人可以建议更简单的方法?我现在不是很好,所以我只使用协同程序进行简单的操作。

先感谢您!

android kotlin kotlinx.coroutines
1个回答
0
投票

你需要在你的协同程序的呼叫站点(你想要使用你的协同程序,例如当前实现中的CoroutineScope)扩展coRout.ui.launch。这样,您不必在任何地方编写和重复coRout.ui.launch,而且,您可以避免当前代码中的内存泄漏(因为您的协同程序可以在您的调用对象想要被销毁时保持活动状态)

例如,如果你在一个类中,你可以让你的类扩展CoroutineScope,如下所示:

class SomeClass: CoroutineScope {
    val job = Job()
    override val coroutineContext: CoroutineContext
        get() = job + coRout.net.coroutineContext
}

在这个课程中,您可以使用launchwithContext轻松处理您的协同程序。当你知道你的类被摧毁时,你也可以cancel() job对象(比如onDestory用于android活动),这样这个类的所有协同程序都会被取消。

© www.soinside.com 2019 - 2024. All rights reserved.