Android应用添加无限循环后界面无法渲染启动失败怎么解决
问题原因
- 错误重写了
Thread的start()方法,该方法本身在主线程(UI线程)执行:你在onCreate中调用MyThread().start(),onCreate的运行线程就是主线程,start()方法内除super.start()外的逻辑都在主线程运行 - 无限循环
while(true)直接阻塞了主线程,Android所有UI绘制、控件渲染、交互响应都由主线程调度,主线程被占后无法执行绘制任务,所以界面完全无法加载
修复方案
核心改动是将子线程要执行的逻辑从start()方法迁移到run()方法中,run()方法内的代码才会运行在你创建的子线程中,不会阻塞主线程。
修复后的完整代码:
class MainActivity : AppCompatActivity() { lateinit var webview: WebView // 标记子线程运行状态,页面销毁时终止循环避免内存泄漏 private var isThreadRunning = true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) webview = findViewById(R.id.browser) MyThread().start() } inner class MyThread : Thread() { // 重写run方法而非start方法,逻辑运行在子线程 override fun run() { while (isThreadRunning) { runOnUiThread { updateWebView() } sleep(60000L) } } } private fun updateWebView() { webview.loadUrl("https://api.site.com/?action=status&device_osversion=${Build.VERSION.SDK_INT}&device_release=${Build.VERSION.RELEASE}&device_device=${Build.DEVICE}&device_model=${Build.MODEL}") } override fun onDestroy() { super.onDestroy() // 页面销毁时终止循环,避免后台无效运行 isThreadRunning = false } }
优化建议
- 除了自定义线程的方案,也可以用
Handler+postDelayed实现同样的定时更新逻辑,代码更简洁,也更易控制生命周期 - 频繁调用
loadUrl更新WebView可以换成调用JS方法更新局部内容,减少页面重加载的性能消耗
内容的提问来源于stack exchange,提问作者Kir
相关产品推荐
相关产品推荐

