Kotlin Compose中CountDownTimer调用函数失败及.random()重复问题
问题1:Unresolved reference: skipWord
原因
你定义的object Timer是全局单例,和GameViewModel的实例完全独立,它无法访问ViewModel中的skipWord()方法。而且全局单例Timer容易引发内存泄漏(比如持有页面引用但不随页面销毁)。
解决方案
把Timer移到GameViewModel内部作为成员变量,让它和ViewModel绑定,这样既能直接调用skipWord(),还能利用ViewModel的生命周期避免泄漏。
修改后的ViewModel代码片段:
class GameViewModel : ViewModel() { private var timer: CountDownTimer? = null // ... 原有代码 ... fun skipWord() { updateGameState(_uiState.value.score) updateUserGuess("") } private fun startTimer() { // 先取消旧Timer,避免多个计时器同时运行 timer?.cancel() timer = object : CountDownTimer(60000, 1000) { override fun onTick(millisUntilFinished: Long) { // 可选:在这里更新UI显示剩余时间,比如同步到_uiState // _uiState.value = _uiState.value.copy(remainingTime = millisUntilFinished / 1000) } override fun onFinish() { skipWord() // 现在可以直接调用ViewModel内的方法 } }.start() } private fun pickRandomWordAndShuffle(): String { // 先循环选出未使用的单词 val selectedWord = generateSequence { if (currentLanguage == "English") engWords.random() else finWords.random() }.first { !usedWords.contains(it) } currentWord = selectedWord setPointAmount() startTimer() // 调用ViewModel内部的启动计时器方法 usedWords.add(selectedWord) return shuffleCurrentWord(selectedWord) } override fun onCleared() { super.onCleared() timer?.cancel() // ViewModel销毁时取消计时器,防止内存泄漏 } // ... 原有代码 ... }
问题2:.random()总是返回重复单词
原因
默认的List.random()使用系统自动播种的全局随机器,正常不会重复。你的问题大概率是原代码逻辑缺陷:先赋值单词、启动计时器,再检查是否已使用,重复时递归调用方法,导致多次触发随机选择却没正确过滤重复项,甚至启动多个无效计时器。
解决方案
用generateSequence或do-while循环先筛选出未使用的单词,再执行后续操作。如果仍有重复,可显式指定随机器:
// 替换List.random()为显式索引选择 engWords[Random.Default.nextInt(engWords.size)]
另外要注意:当usedWords包含所有单词时,要添加重置逻辑(比如清空usedWords),避免循环无限运行。
内容的提问来源于stack exchange,提问作者Luovahulluus
相关产品推荐
相关产品推荐

