我有两个挂起功能:
suspend fun sendData() : Boolean
suspend fun awaitAcknowledge() : Boolean
Run Code Online (Sandbox Code Playgroud)
我想将它们包装在第三个挂起函数中,它们应该在其中并行执行,并且我想通过具有两个返回值来计算最终结果:
suspend fun sendDataAndAwaitAcknowledge() : Boolean {
// TODO execute both in parallel and compare both results
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样写的话,
suspend fun sendDataAndAwaitAcknowledge() : Boolean {
val sendResult = sendData()
val receiveAck = awaitAcknowledge()
}
Run Code Online (Sandbox Code Playgroud)
这些函数将按串行顺序执行,这在我的情况下不起作用。
来自 RxJava,我想实现类似zip操作符的功能:
Single.zip(awaitAcknowledge(), sendData(), {receiveAck, sendResult -> ...})
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点Coroutines?
我注意到,combine() 函数最多只能接受 5 个流的参数
public fun <T1, T2, T3, T4, T5, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
transform: suspend (T1, T2, T3, T4, T5) -> R
): Flow<R> = combineUnsafe(flow, flow2, flow3, flow4, flow5) { args: Array<*> ->
transform(
args[0] as T1,
args[1] as T2,
args[2] as T3,
args[3] as T4,
args[4] as T5
)
}
Run Code Online (Sandbox Code Playgroud)
这背后有什么特殊原因吗?(或者可能不是?)
如果我在本地文件中定义一个有6个参数的combine(),例如
private fun <T1, T2, T3, T4, T5, T6, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>, …Run Code Online (Sandbox Code Playgroud) 我的 viewModel 中有 2 个 stateFlow。为了将它们收集到片段中,我必须启动协程两次,如下所示:
lifecycleScope.launchWhenStarted {
stocksVM.quotes.collect {
if (it is Resource.Success) {
it.data?.let { list ->
quoteAdapter.submitData(list)
}
}
}
}
lifecycleScope.launchWhenStarted {
stocksVM.stockUpdate.collect {
log(it.data?.data.toString())
}
}
Run Code Online (Sandbox Code Playgroud)
如果我有更多的 stateFlow,我必须分别启动协程。有没有更好的方法来处理我的片段/活动或其他地方的多个 stateFlow?
我想实现什么目标?
我有一个下载图像的任务,但随着屏幕滚动,它将取消以前的下载并开始下载新的图像。我希望当它取消coroutine下载上一个图像时,它会立即停止并释放bandwidth新图像,以便更快地下载。
我已经尝试过什么?
我尝试了多种方法来停止,coroutine但即使在取消后,它仍然会继续进行,直到完成下载coroutine。当我取消它时,它会生成coroutine一个变量并停止调用进一步的挂起函数。但问题是,如果它运行多次或从该任务下载图像,除非完成,否则不会取消。Like 循环将完成其迭代,然后协程将被取消。isActivefalseloop1000000network1000000
我已经尝试过这些但没有成功:
job.cancel()
scope.cancel()
Run Code Online (Sandbox Code Playgroud)
我尝试了很多方法来实现这一目标,但没有找到解决方案。我现在无法在我的项目中使用任何库。
这个用例不是通过线程、执行器服务、协程来实现的。因为所有人的行为都是一样的。
更多类似的问题:
我在使用 Kotlin Flow 时遇到了问题。
我从官方指南中复制了以下代码
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
delay(100)
emit(i)
}
}
Run Code Online (Sandbox Code Playgroud)
但Android Studio提示如下错误:
Flow 类不需要类型参数
我究竟做错了什么?
我是测试新手,试图获取第二个流量值并断言它,当我逐个运行此测试时运行良好,但是当我运行整个测试时,第一个测试运行良好,其余测试给我超时错误。
错误 :
After waiting for 60000 ms, the test coroutine is not completing
kotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 60000 ms, the test coroutine is not completing
at app//kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$3$3.invokeSuspend(TestBuilders.kt:304)
(Coroutine boundary)
Run Code Online (Sandbox Code Playgroud)
@OptIn(ExperimentalCoroutinesApi::class)
class HomeViewModelTest {
private lateinit var viewModel: HomeViewModel
private val testDispatcher = UnconfinedTestDispatcher()
@Before
fun setup() {
viewModel = HomeViewModel(FakeOrderRepository())
Dispatchers.setMain(testDispatcher)
}
@After
fun tearDown() {
Dispatchers.resetMain()
testDispatcher.cancel()
}
@Test
fun flowViewModelTesting1() = runTest {
val result = viewModel.homeUiState.drop(1).first()
assertThat(true).isTrue()
}
@Test
fun flowViewModelTesting2() = runTest {
val result …Run Code Online (Sandbox Code Playgroud) 试图为Kotlin协程运行一些示例,但无法构建我的项目。我正在使用最新的gradle版本-4.1
有什么建议要检查/修复吗?
这是 build.gradle
buildscript {
ext.kotlin_version = '1.1.4-3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
kotlin {
repositories {
jcenter()
}
experimental {
coroutines 'enable'
}
dependencies {
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.18"
}
}
Run Code Online (Sandbox Code Playgroud)
和 main.kt
fun main(args: Array<String>) {
launch (CommonPool) {
delay(1000L)
println("World!")
}
println("Hello, ")
Thread.sleep(2000L)
}
Run Code Online (Sandbox Code Playgroud)
当我跑步时,gradle compileKotlin我得到以下内容
e: /Users/philippgrigoryev/projects/kotlin-coroutines/src/main/kotlin/main.kt: (2, 5): Unresolved reference: launch
e: /Users/philippgrigoryev/projects/kotlin-coroutines/src/main/kotlin/main.kt: (2, 13): Unresolved reference: CommonPool
e: /Users/philippgrigoryev/projects/kotlin-coroutines/src/main/kotlin/main.kt: (3, 9): …Run Code Online (Sandbox Code Playgroud) 我有一个具体例子的一般性问题:在拍照时,我想在Android中使用Kotlin协程魔法而不是回调地狱.
manager.openCamera(cameraId, object : CameraDevice.StateCallback() {
override fun onOpened(openedCameraDevice: CameraDevice) {
println("Camera onOpened")
// even more callbacks with openedCameraDevice.createCaptureRequest()....
}
override fun onDisconnected(cameraDevice: CameraDevice) {
println("Camera onDisconnected")
cameraDevice.close()
}
...
Run Code Online (Sandbox Code Playgroud)
我怎么把它转换成......错误......不那么难看的东西? 是否可以使用三个左右的函数进行平均回调,并通过将主流指定为promise-result路径将其转换为promise链? 如果是这样,我应该/我是否应该使用协同程序使其异步?
我喜欢async和.await会产生的东西
manager.open(cameraId).await().createCaptureRequest()
Run Code Online (Sandbox Code Playgroud)
我试图通过以下内容来做到这一点,但是...我不认为我正在使用CompletableDeferred!
suspend fun CameraManager.open(cameraId:String): CameraDevice {
val response = CompletableDeferred<CameraDevice>()
this.openCamera(cameraId, object : CameraDevice.StateCallback() {
override fun onOpened(cameraDevice: CameraDevice) {
println("camera onOpened $cameraDevice")
response.complete(cameraDevice)
}
override fun onDisconnected(cameraDevice: CameraDevice) {
response.completeExceptionally(Exception("Camera onDisconnected $cameraDevice"))
cameraDevice.close()
}
override fun onError(cameraDevice: CameraDevice, error: Int) {
response.completeExceptionally(Exception("Camera onError $cameraDevice …Run Code Online (Sandbox Code Playgroud) 我有以下课程:
class Repository(
private val assetManager: AssetManager,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) {
suspend fun fetchHeritagesList(): HeritageResponse = withContext(ioDispatcher) {
try {
// TODO Blocking method call?
val bufferReader = assetManager.open("heritages.json").bufferedReader()
...
Run Code Online (Sandbox Code Playgroud)
open("heritages.json")我想知道为什么我会在这句话中收到警告Innapropriate blocking method call?修复不是withContext(ioDispatcher)这样的吗?
感谢您的解释!
在 Jetpack compose 中,我们可以选择使用rememberCoroutineScope()和使用LaunchedEffect可组合物以使用协程/运行挂起功能(显示小吃店等)。
到目前为止,我采用的约定是记住我的 compose 树顶部的单个协程作用域,并通过函数参数将其传递到需要它的地方。这似乎是一个很好的做法,但另一方面,它给我的函数签名增加了额外的噪音。
LaunchedEffectoverrememberCoroutineScope()内部可组合函数?rememberCoroutineScope()实际启动协程的每个函数?