【问题标题】:Coroutine Job operation at the push of a button协程作业一键操作
【发布时间】:2021-06-20 16:23:03
【问题描述】:

变量声明

private lateinit var wayoJob: Job
override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + wayoJob

功能

@InternalCoroutinesApi
private fun startRepeatingJob(timeInterval: Long): Job {
    return CoroutineScope(Dispatchers.Default).launch {
        while (NonCancellable.isActive) {

            Log.i("API", "UPDATE")

            delay(timeInterval)
        }
    }
}

在开始按钮中

wayoJob = startRepeatingJob(5000L)

在 Button end 和 onDestroy()

wayoJob.cancel()

当我点击结束按钮时,它返回一个错误:

原因:kotlin.UninitializedPropertyAccessException:lateinit 属性 wayoJob 尚未初始化

有没有办法解决这个问题?

我必须做一个功能,当我按下一个按钮时每隔几秒钟开始执行一次,当我点击另一个按钮时会结束。

编辑:

我可以用我自己的 shouldBeActive 值尝试这样的事情,并在需要时运行,但这不是应该的

var shouldBeActive = false

@InternalCoroutinesApi
private fun startRepeatingJob(timeInterval: Long): Job {
    return CoroutineScope(Dispatchers.Default).launch {
        while (NonCancellable.isActive && shouldBeActive) {

            Log.i("API", "UPDATE")

            delay(timeInterval)
        }
    }
}

【问题讨论】:

  • 确定开始按钮中的那一行正在运行吗?如果正在初始化变量,则不应发生该错误,这会发生。
  • @RyanM 是的,已初始化。我添加了一个日志,它每 5 秒显示一次。当我点击停止时,它会抛出一个没有初始化的错误
  • @RyanM 我找到了解决方案。检查答案
  • 为什么你要为你的班级展示实现CoroutineScope的代码,但你却从不使用它,而是使用一个临时的CoroutineScope(Default)?此外,顶级工作不应该是不断变化的lateinit var。您似乎在使用结构化并发的语法元素,但破坏了结构化并发本身。
  • 您的错误消息证实了我上面所说的内容,您的解决方案只是针对实际问题添加了更多技巧。

标签: android kotlin kotlin-coroutines coroutine


【解决方案1】:

我找到了解决办法。

我有一个 Activity 重新加载并且对象重置

解决方案是像下面这样插入它。此解决方案可确保在此期间不会创建第二个对象

companion object {
    private lateinit var wayoJob: Job
}

全班示例:

class StartActivity : AppCompatActivity(), CoroutineScope {
    companion object {
        private lateinit var wayoJob: Job
    }

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + wayoJob

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_start)
    }

    @InternalCoroutinesApi
    private fun startRepeatingJob(timeInterval: Long): Job {
        return CoroutineScope(Dispatchers.Default).launch {
            while (NonCancellable.isActive) {

                Log.i("API", "UPDATE")

                delay(timeInterval)
            }
        }
    }

    @InternalCoroutinesApi
    fun endBtnOnClick(view: View?) {
        wayoJob.cancel()
    }

    @InternalCoroutinesApi
    fun startBtnOnClick(view: View?) {
        wayoJob = startRepeatingJob(5000L)
    }

    override fun onDestroy() {
        super.onDestroy()
        wayoJob.cancel()
    }
}

【讨论】:

  • 如果同时存在多个StartActivitys,这种方法会引入错误。 Job 应该是针对每个实例的,而不是全局的。
猜你喜欢
  • 2019-09-27
  • 2022-12-20
  • 1970-01-01
  • 2020-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 2021-04-22
相关资源
最近更新 更多