标签: coroutinescope

如何停止或取消 Kotlin 协程(立即停止当前运行的代码块)?

我想实现什么目标?

我有一个下载图像的任务,但随着屏幕滚动,它将取消以前的下载并开始下载新的图像。我希望当它取消coroutine下载上一个图像时,它会立即停止并释放bandwidth新图像,以便更快地下载。

我已经尝试过什么?

我尝试了多种方法来停止,coroutine但即使在取消后,它仍然会继续进行,直到完成下载coroutine。当我取消它时,它会生成coroutine一个变量并停止调用进一步的挂起函数。但问题是,如果它运行多次或从该任务下载图像,除非完成,否则不会取消。Like 循环将完成其迭代,然后协程将被取消。isActivefalseloop1000000network1000000

我已经尝试过这些但没有成功:

job.cancel()
scope.cancel()
Run Code Online (Sandbox Code Playgroud)

我尝试了很多方法来实现这一目标,但没有找到解决方案。我现在无法在我的项目中使用任何库。

这个用例不是通过线程、执行器服务、协程来实现的。因为所有人的行为都是一样的。

更多类似的问题:

如何取消 kotlin 协程以进行阻塞下载操作

AsyncTask 不会取消 android 中长时间运行的操作

协程持有的服务泄漏

android coroutine kotlin kotlin-coroutines coroutinescope

21
推荐指数
2
解决办法
3万
查看次数

如何将 Android DataStore 与多用户或文件一起使用

我想使用 DataStore 存储一些首选项。但问题是我的应用程序可以有多个用户,因此需要将这些首选项存储在单独的文件中。我得到了一个仅使用一个用户的工作示例,但我正在努力支持多个用户。

这是我的代码的示例:

class DataStorageRepository(private val context: Context, private val userRepository: UserRepository) {

    private object PreferencesKeys {
        val SETTING_ONE = intPreferencesKey("setting_one")
    }

    // retrieve datastore for currently logged in user. 
    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = userRepository.currentRegistration().name)

    val userPreferencesFlow: Flow<UserPreferences> = context.dataStore.data.map { preferences ->
        val settingOne = preferences[PreferencesKeys.SETTING_ONE] ?: 0

        UserPreferences(settingOne)
    }

    suspend fun storeSettingOne(settingOne: Int) {
        context.dataStore.edit { preferences ->
            preferences[PreferencesKeys.SETTING_ONE] = settingOne
        }
    }

    data class UserPreferences(val lastUsedToAccountTab: Int)
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Koin并尝试卸载DataStorageRepository注销并在登录时重新创建它,但数据存储似乎一直保持活动状态,直到应用程序被终止并且出现以下崩溃: …

android koin android-jetpack coroutinescope android-jetpack-datastore

17
推荐指数
4
解决办法
1万
查看次数

Kotlin 中 CoroutineScope 和 coroutineScope 的区别

任何人都可以明确功能之间的关系 CoroutineScope()coroutineScope()?

当我尝试检查源代码时,我发现它们都是CoroutineScope.kt. 此外,coroutineScope()suspend函数而另一个是normal函数

以下是我可以找到的文档:

/**
 * Creates a [CoroutineScope] that wraps the given coroutine [context].
 *
 * If the given [context] does not contain a [Job] element, then a default `Job()` is created.
 * This way, cancellation or failure or any child coroutine in this scope cancels all the other children,
 * just like inside [coroutineScope] block.
 */
@Suppress("FunctionName")
public fun CoroutineScope(context: CoroutineContext): CoroutineScope =
    ContextScope(if (context[Job] != …
Run Code Online (Sandbox Code Playgroud)

android suspend kotlin kotlin-coroutines coroutinescope

11
推荐指数
3
解决办法
9204
查看次数

获取流的收集中的当前和先前值

我需要处理流收集中的当前值和先前值,因此我需要一些具有如下作用的运算符:

----A----------B-------C-----|--->

---(null+A)---(A+B)---(B+C)--|--->
Run Code Online (Sandbox Code Playgroud)

一个想法是这样的:

fun <T: Any> Flow<T>.withPrevious(): Flow<Pair<T?, T>> = flow {
    var prev: T? = null
    this@withPrevious.collect {
        emit(prev to it)
        prev = it
    }
}
Run Code Online (Sandbox Code Playgroud)

但这样就无法控制执行第一个流程的上下文。有没有更灵活的解决方案?

coroutine kotlin kotlin-coroutines coroutinescope kotlin-flow

10
推荐指数
2
解决办法
8576
查看次数

在协程范围内调用时启动不执行

我在协程范围内调用 launch 但它不执行。Snackbar 操作监听器正在执行,但启动块由于某种原因没有执行。

CoroutineScope(Dispatchers.Main).launch {
    val scope = this
    val mn = snackbarManager(R.id.root)
    Snackbar
        .make(mn.container, R.string.recpt_deleted, Snackbar.LENGTH_LONG)
        .setAction(R.string.undo) {
            scope.launch { // not executing
                Toast.makeText(requireContext(),"Committing",Toast.LENGTH_LONG).show()
                Log.d("COMMIT", "calling commit")
            }
        }
        .show()
}
Run Code Online (Sandbox Code Playgroud)

android kotlin android-snackbar kotlin-coroutines coroutinescope

9
推荐指数
1
解决办法
5908
查看次数

kotlin coroutines,coroutineScope和withContext有什么区别

withContext
suspend fun <T> withContext(
    context: CoroutineContext, 
    block: suspend CoroutineScope.() -> T
): T (source)
Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns the result.
Run Code Online (Sandbox Code Playgroud)
suspend fun <R> coroutineScope(
    block: suspend CoroutineScope.() -> R
): R (source)
Creates a CoroutineScope and calls the specified suspend block with this scope. The provided scope inherits its coroutineContext from the outer scope, but overrides the context’s Job.
Run Code Online (Sandbox Code Playgroud)

withContext采用CoroutineContext,并且似乎都complete在其所有子级完成之后。

在什么情况下,withContext或者coroutineScope应该比其他的首选? …

kotlin-coroutines coroutinescope withcontext

8
推荐指数
1
解决办法
395
查看次数

如何正确加入 CoroutineScope 中启动的所有作业

GlobalScope我正在重构一些目前在基于结构化并发的方法上启动协程的 Kotlin 代码。我需要在 JVM 退出之前加入代码中启动的所有作业。我的类可以分解为以下接口:

interface AsyncTasker {
    fun spawnJob(arg: Long)
    suspend fun joinAll()
}
Run Code Online (Sandbox Code Playgroud)

用法:

fun main(args: Array<String>) {
    val asyncTasker = createAsyncTasker()

    asyncTasker.spawnJob(100)
    asyncTasker.spawnJob(200)
    asyncTasker.spawnJob(300)
    asyncTasker.spawnJob(500)

    // join all jobs as they'd be killed when the JVM exits
    runBlocking {
        asyncTasker.joinAll()
    }
}
Run Code Online (Sandbox Code Playgroud)

基于我的GlobalScope实现如下所示:

class GlobalScopeAsyncTasker : AsyncTasker {
    private val pendingJobs = mutableSetOf<Job>()

    override fun spawnJob(arg: Long) {
        var job: Job? = null
        job = GlobalScope.launch(Dispatchers.IO) {
            someSuspendFun(arg)
            pendingJobs.remove(job)
        }
        pendingJobs.add(job)
    }

    override suspend …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-coroutines coroutinescope

8
推荐指数
1
解决办法
2909
查看次数

CoroutineScope(job+Dispatchers.Main) 如何在主/UI 线程上运行?

如果内部的操作在CoroutineScope(job+Dispatchers.Main){...}主线程上运行,那么它为什么不违反 Android 的要求,即不允许在主/UI 线程上运行慢(阻塞)操作(网络等)?我可以在此范围内运行阻塞操作,并且 UI 根本不会冻结。

如果有人能解释幕后发生的事情,我将不胜感激。我的猜测是它类似于 JavaScript 如何使用事件循环管理阻塞操作,但我很难找到任何相关材料。

android android-thread kotlin-coroutines coroutinescope

7
推荐指数
2
解决办法
1436
查看次数

自定义协程作用域到底是什么?

我对协程-调度程序-生命周期范围-异步等待有足够的了解。很明显,所有scope.launch函数都会返回我们可以管理协程生命周期的作业。我唯一无法理解的是我们使用自定义作业创建的自定义范围。

例如:

val myJob = Job()

val customCoroutineScope= CoroutineScope(Dispatchers.IO+myJob)

我认为在这些代码片段之后我可以启动范围并管理它的生命周期和 myJob 引用的内容,但它不起作用。有人可以向我解释一下这个自定义范围的目的和好处吗?

android asynchronous kotlin kotlin-coroutines coroutinescope

7
推荐指数
1
解决办法
5504
查看次数

使用 GlobalScope.launch 和 CoroutineScope().launch 启动协程有区别吗?

在 Kotlin 中启动协程有多种方法。我发现了几个使用GlobalScope和的例子CoroutineScope。但后一个是在启动协程时直接创建的:

  1. 使用GlobalScope

    fun loadConfiguration() {
        GlobalScope.launch(Dispatchers.Main) {
           val config = fetchConfigFromServer() // network request
           updateConfiguration(config)
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用CoroutineScope实例,在启动协程时直接创建:

    fun loadConfiguration() {
        CoroutineScope(Dispatchers.Main).launch {
            val config = fetchConfigFromServer() // network request
            updateConfiguration(config)
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

在这种情况下,这两种方法有区别吗?

第二种情况不是违反了结构化并发的原则吗?

android kotlin kotlin-coroutines coroutinescope structured-concurrency

6
推荐指数
1
解决办法
9684
查看次数