Kotlin中do while循环搭配Handler.postDelayed导致APP黑屏无报错问题求助
问题根因
你写的do{}while(i==5)是无限死循环,直接阻塞了安卓主线程:
- 安卓所有UI绘制、用户交互响应、消息队列消费都在主线程执行,死循环会导致主线程无法处理其他任务,直接触发ANR(应用无响应),表现为黑屏、无反应
- 循环中你不断往Handler消息队列塞延迟任务,但主线程卡在死循环中完全没有机会消费这些消息,
StarQuizy也不会按你预期的间隔执行
解决思路
你要实现每隔17秒迭代调用StarQuizy的需求,不需要写循环控制,只需要在每次执行StarQuizy后,主动post下一次的延迟任务即可。如果需要中途停止逻辑,调用Handler移除对应的Runnable即可。
修正后的代码示例
// 定义全局可复用的Runnable private lateinit var quizRunnable: Runnable override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_quizy_app) milisecond = 0 rightAnswer = findViewById(R.id.txtRightAnswer) txtQuestion = findViewById(R.id.txtQuestion) edtAnswer = findViewById(R.id.edtAnswer) progressbar = findViewById(R.id.progresscircle) txtProgress = findViewById(R.id.textprogress) handler = Handler(Looper.getMainLooper()) // 初始化Runnable,执行完自动post下一次 quizRunnable = Runnable { StarQuizy() handler?.postDelayed(quizRunnable, 17000) } // 首次调用 StarQuizy() // 首次延迟调用 handler?.postDelayed(quizRunnable, 17000) } fun StarQuizy(){ random = Random question = Question[random.nextInt(Question.size)] txtQuestion?.text = mixLetter(question) countDownTimer() } fun countDownTimer(){ cTimer = object :CountDownTimer(15000, 1000){ override fun onTick(millisUntilFinished: Long) { milisecond = millisUntilFinished rightAnswer?.setText("${milisecond!!/1000}") } override fun onFinish() {} }.start() } // 页面销毁时移除回调,避免内存泄漏和后台无效执行 override fun onDestroy() { super.onDestroy() handler?.removeCallbacks(quizRunnable) cTimer?.cancel() }
补充注意点
- 不要在主线程执行任何死循环、长耗时逻辑,这类逻辑必须放到子线程执行
- Handler初始化建议显式传入
Looper.getMainLooper(),避免隐式获取Looper的潜在问题 - 页面销毁时一定要移除Handler的未执行回调,同时取消CountDownTimer,避免内存泄漏
内容的提问来源于stack exchange,提问作者Aung Phyo Zaw
相关产品推荐
相关产品推荐

