通过RunOnUIThread修改MainActivity按钮颜色崩溃:未初始化属性异常
解决TCP Socket回调中修改按钮颜色时的lateinit属性未初始化异常
问题原因
- 在
MainHandler中通过MainActivity()创建了新的Activity实例,该实例未执行onCreate方法,导致BTNStatus05这个lateinit属性从未被初始化,访问时抛出kotlin.UninitializedPropertyAccessException。 - 错误地尝试通过新建Activity实例调用
runOnUiThread,这完全没必要,且会导致访问未初始化的控件。
修复方案
- 复用当前Activity实例:
MainHandler是MainActivity的内部类,可直接访问外部类的控件实例,无需新建Activity对象。 - 确保UI操作在主线程执行:你的
MainHandler使用主线程Looper初始化,handleMessage方法本身就在主线程中运行,无需额外调用runOnUiThread。
修改后的MainHandler代码如下:
inner class MainHandler(mainlooper: Looper) : Handler(mainlooper) { private val TAG = "MainActivity" val mapper = jacksonObjectMapper() override fun handleMessage(msg: Message) { Log.d(TAG, "Handle") super.handleMessage(msg) val jsonstr = msg?.obj as String val jsontree = mapper.readTree(jsonstr) val type = jsontree.get("type").asText() Log.d(TAG, "Mainhandler: jsonstr - " + jsonstr) Log.d(TAG, "MainHandler:Json type - " + type ) when(type) { "button" -> { Log.d(TAG, "We got button update: " + type) // 直接操作当前Activity的按钮控件 BTNStatus05.setBackgroundColor(Color.YELLOW) BTNStatus05.setEnabled(false) } else -> Log.d(TAG, "unknown what " + type) } } }
额外注意事项
- 永远不要手动创建Activity实例(如
MainActivity()),Activity的生命周期由Android系统管理,手动创建的实例不会执行onCreate等生命周期方法,控件自然无法初始化。 - 如果你的Handler是在子线程Looper中运行,此时才需要用
runOnUiThread包裹UI操作,但你的场景中MainHandler已经绑定主线程Looper,所以无需此操作。
内容的提问来源于stack exchange,提问作者Jesper Blom
相关产品推荐
相关产品推荐

