You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EventBus更新Android Auto屏幕触发IllegalStateException问题

Android Auto中EventBus更新状态后界面不渲染且抛出IllegalStateException的修复方案

问题场景

尝试通过EventBus更新Android Auto屏幕状态并重新渲染,编写了CarPlayScreen代码后,初始模板可正常显示,但触发onCapsuleStateUpdate方法后界面未更新,同时控制台抛出异常。

原代码

package com.capsule

import androidx.car.app.CarContext
import androidx.car.app.Screen
import androidx.car.app.model.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


class CarPlayScreen(carContext: CarContext) : Screen(carContext) {

    private var template: Template
    private var eventBus = EventBus.getDefault()

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onCapsuleStateUpdate(state: CapsuleState) {
        template = GridTemplate.Builder()
            .setTitle("Temperature: ${state.temperature}C")
            .build()
    }


    init {
        eventBus.register(this)

        val row = Row.Builder()
            .setTitle("Wait state update")
            .build()
        val pane = Pane.Builder()
            .addRow(row)
            .build()

        template = PaneTemplate.Builder(pane)
            .setHeaderAction(Action.APP_ICON)
            .build()

        invalidate()
    }

    override fun onGetTemplate(): Template {
        return template
    }

}

错误日志

E  Could not dispatch event: class com.capsule.CapsuleState to subscribing class class com.capsule.CarPlayScreen
java.lang.IllegalStateException: Template is in a loading state but lists are added, or vice versa
at androidx.car.app.model.GridTemplate$Builder.build(GridTemplate.java:282)
at com.capsule.CarPlayScreen.onCapsuleStateUpdate(CarPlayScreen.kt:24)
at java.lang.reflect.Method.invoke(Native Method)
at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:517)
at org.greenrobot.eventbus.EventBus.postToSubscription(EventBus.java:444)
at org.greenrobot.eventbus.EventBus.postSingleEventForEventType(EventBus.java:421)
at org.greenrobot.eventbus.EventBus.postSingleEvent(EventBus.java:394)
at org.greenrobot.eventbus.EventBus.post(EventBus.java:275)
at com.capsule.CapsuleBleManager.followState$lambda$10(CapsuleBleManager.kt:190)
at com.capsule.CapsuleBleManager.$r8$lambda$6x0OdCCBxFndfQ6AFD4N11VDXro(Unknown Source:0)
at com.capsule.CapsuleBleManager$$ExternalSyntheticLambda0.onDataReceived(Unknown Source:2)
at no.nordicsemi.android.ble.ValueChangedCallback.lambda$notifyValueChanged$0(ValueChangedCallback.java:184)
at no.nordicsemi.android.ble.ValueChangedCallback$$ExternalSyntheticLambda1.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:914)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7560)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

错误提示

IllegalStateException – if the template is in a loading state but there are lists added, or vice versa, or if the template does not have either a title or header Action set.


修复方案

1. 修正GridTemplate的构建逻辑

异常核心原因是你创建的GridTemplate不符合Android Auto的模板规范:既没有添加网格内容,也没有标记为加载状态,触发了非法状态校验。

修改onCapsuleStateUpdate方法,二选一即可:

  • 方案A:添加合法的网格内容
@Subscribe(threadMode = ThreadMode.MAIN)
fun onCapsuleStateUpdate(state: CapsuleState) {
    // 创建网格项
    val tempGridItem = GridItem.Builder()
        .setTitle("当前温度")
        .setText("${state.temperature}℃")
        .build()
    
    // 构建合法的GridTemplate
    template = GridTemplate.Builder()
        .setTitle("温度监控")
        .addGridItem(tempGridItem) // 必须添加至少一个网格项
        .setHeaderAction(Action.APP_ICON) // 可选,保持头部动作一致性
        .build()
    
    // 通知框架重新渲染
    invalidate()
}
  • 方案B:设置加载状态(如果需要等待数据)
@Subscribe(threadMode = ThreadMode.MAIN)
fun onCapsuleStateUpdate(state: CapsuleState) {
    template = GridTemplate.Builder()
        .setTitle("更新中...")
        .setLoading(true) // 标记为加载状态,此时不能添加网格项
        .build()
    
    invalidate()
}

2. 补充模板更新的关键步骤

更新template变量后,必须调用invalidate()方法,通知Android Auto框架重新获取并渲染新模板。原代码在事件回调中遗漏了这一步,这也是界面不更新的直接原因。

3. 优化EventBus生命周期管理(推荐)

为避免内存泄漏,在屏幕销毁时注销EventBus:

override fun onDestroy() {
    super.onDestroy()
    eventBus.unregister(this)
}

内容的提问来源于stack exchange,提问作者Timur Ruziev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:53:08