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

Jetpack Glance Widget用LazyColumn触发TransactionTooLargeException求助

解决Glance Widget列表过多导致TransactionTooLargeException的方案

你遇到的android.os.TransactionTooLargeException本质是Glance Widget更新时,序列化后的UI数据体积超过了Android Binder进程间通信的大小限制。添加GlanceTheme后,主题相关的额外序列化数据进一步增大了数据包,导致原本能运行的50条条目也触发了崩溃。以下是无需缩减条目数的可行解决方案:

1. 分批更新Widget

不要一次性将所有列表数据传递给Widget,拆分数据后分多次调用更新接口,避免单次传输的数据量超标:

class MyListWidget : GlanceAppWidget() {
    override suspend fun provideGlance(context: Context, id: GlanceId) {
        // 先加载第一部分数据
        val firstBatchData = getDataBatch(0, 30)
        updateAppWidget(context, id, buildGlanceContent(firstBatchData))
        
        // 延迟加载第二部分数据
        delay(1000)
        val secondBatchData = getDataBatch(30, 60)
        updateAppWidget(context, id, buildGlanceContent(firstBatchData + secondBatchData))
    }
    
    private fun buildGlanceContent(data: List<Item>) = run {
        GlanceTheme {
            LazyColumn {
                items(data) { item ->
                    Text(item.title)
                }
            }
        }
    }
}

注意:避免过于频繁的更新,可结合WorkManager调度分批任务,减少系统资源消耗。

2. 优化列表项UI复杂度

每个Glance Compose元素都会被序列化传输,简化列表项能大幅降低数据包体积:

  • 移除不必要的UI元素:比如非核心的图标、装饰性Divider、冗余的文本描述
  • 避免嵌套复杂组件:尽量使用Glance提供的基础组件(Text、Icon),减少自定义Compose节点
  • 关闭不必要的状态:如果列表项无需交互状态(如选中、展开),不要保留多余的状态变量

3. 精简传输数据

不要传递完整的实体类,只保留Widget展示必需的字段:

// 原实体类(冗余字段多)
data class FullItem(val id: Long, val title: String, val content: String, val createTime: Long, val author: String)

// 精简后的Widget专用数据类
data class WidgetItem(val title: String, val shortContent: String)

// 转换方法
fun FullItem.toWidgetItem() = WidgetItem(title, content.take(50))

对长文本进行截断或压缩,进一步减少数据体积。

4. 实现Widget内分页加载

限制Widget单次展示的条目数量,提供交互触发分页更新:

  • 在Widget底部添加“加载更多”按钮,通过Action触发更新,加载下一批数据
  • 或者根据Widget的显示高度,只加载当前可见区域的条目,滚动时触发后续加载(注意Glance的LazyColumn交互能力有限,需结合ActionCallback实现)
  • 若Widget空间不足,可添加“查看全部”按钮,跳转至App查看完整列表

5. 精简GlanceTheme配置

默认GlanceTheme会序列化大量主题属性,自定义精简主题可减少额外开销:

// 自定义精简主题
private val MyWidgetTheme = glanceTheme {
    colors {
        // 只定义Widget用到的颜色
        primary = Color(0xFF2196F3)
        onPrimary = Color.White
    }
    typography {
        // 只定义必要的文本样式
        headlineSmall = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold)
    }
}

// 使用自定义主题
override suspend fun provideGlance(context: Context, id: GlanceId) {
    provideGlanceContent {
        MyWidgetTheme {
            // Widget UI内容
        }
    }
}

如果主题需求简单,甚至可以直接在组件上设置样式,完全省略主题包裹。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:15:00