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

ModalBottomSheet在Release版本(API23)崩溃,求解决方案

API23 Release版本下ModalBottomSheet崩溃问题及临时解决方案

问题现象

Debug版本运行正常,但在**API23(Marshmallow)**的Release版本(即使关闭代码混淆)中,使用ModalBottomSheet会触发如下崩溃:

java.lang.IllegalStateException: The offset was read before being initialized. Did you access the offset in a phase before layout, like effects or composition?
    at androidx.compose.material3.AnchoredDraggableState.requireOffset(AnchoredDraggable.kt:344)
    at androidx.compose.material3.SheetState.requireOffset(SheetDefaults.kt:164)
    at androidx.compose.material3.ModalBottomSheet_androidKt$ModalBottomSheet$3$1$2$1.invoke-Bjo55l4(ModalBottomSheet.android.kt:202)
    at androidx.compose.material3.ModalBottomSheet_androidKt$ModalBottomSheet$3$1$2$1.invoke(ModalBottomSheet.android.kt:198)
    at androidx.compose.foundation.layout.OffsetPxNode$measure$1.invoke(Offset.kt:247)
    at androidx.compose.foundation.layout.OffsetPxNode$measure$1.invoke(Offset.kt:246)
    at androidx.compose.ui.node.LookaheadCapablePlaceable$layout$1.placeChildren(LookaheadDelegate.kt:107)
    at androidx.compose.ui.node.LayoutModifierNodeCoordinator.placeAt-f8xVGno(LayoutModifierNodeCoordinator.kt:167)
    at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:33)
    at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelative(Placeable.kt:417)
    at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelative$default(Placeable.kt:203)
    at androidx.compose.foundation.layout.FillNode$measure$1.invoke(Size.kt:704)
    at androidx.compose.foundation.layout.FillNode$measure$1.invoke(Size.kt:703)
    at androidx.compose.ui.node.LookaheadCapablePlaceable$layout$1.placeChildren(LookaheadDelegate.kt:107)
    at androidx.compose.ui.node.LayoutModifierNodeCoordinator.placeAt-f8xVGno(LayoutModifierNodeCoordinator.kt:167)
    at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:33)
    at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelative(Placeable.kt:417)
    at androidx.compose.ui.layout.Placeable$PlacementScope.placeRelative$default(Placeable.kt:203)
    at androidx.compose.foundation.layout.SizeNode$measure$1.invoke(Size.kt:840)
    at androidx.compose.foundation.layout.SizeNode$measure$1.invoke(Size.kt:839)
    at androidx.compose.ui.node.LookaheadCapablePlaceable$layout$1.placeChildren(LookaheadDelegate.kt:107)
    at androidx.compose.ui.node.LayoutModifierNodeCoordinator.placeAt-f8xVGno(LayoutModifierNodeCoordinator.kt:167)
    at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:33)
    at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:428)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate$placeOuterCoordinatorBlock$1.invoke(LayoutNodeLayoutDelegate.kt:489)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate$placeOuterCoordinatorBlock$1.invoke(LayoutNodeLayoutDelegate.kt:483)
    at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2303)
    at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:500)
    at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:256)
    at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
    at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutModifierSnapshotReads$ui_release(OwnerSnapshotObserver.kt:98)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.placeOuterCoordinator-f8xVGno(LayoutNodeLayoutDelegate.kt:753)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.placeAt-f8xVGno(LayoutNodeLayoutDelegate.kt:724)
    at androidx.compose.ui.layout.Placeable.access$placeAt-f8xVGno(Placeable.kt:33)
    at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50(Placeable.kt:428)
    at androidx.compose.ui.layout.Placeable$PlacementScope.place-70tqf50$default(Placeable.kt:230)
    at androidx.compose.foundation.layout.BoxKt.placeInBox(Box.kt:194)
    at androidx.compose.foundation.layout.BoxKt.access$placeInBox(Box.kt:1)
    at androidx.compose.foundation.layout.BoxMeasurePolicy$measure$5.invoke(Box.kt:174)

复现步骤

使用androidx.compose:compose-bom:2024.06.00创建新Compose项目,替换MainActivity代码为以下内容即可触发崩溃:

package com.example.myapplication

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import com.example.myapplication.ui.theme.MyApplicationTheme

class MainActivity : ComponentActivity() {
    
    @OptIn(ExperimentalMaterial3Api::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyApplicationTheme {
                ModalBottomSheet(
                    onDismissRequest = { }
                ) {
                    Column(Modifier.fillMaxWidth()) {
                        Text(text = "Hello Dear!")
                        Text(text = "Hello Dear!")
                        Text(text = "Hello Dear!")
                        Text(text = "Hello Dear!")
                    }
                }
            }
        }
    }
}

临时解决方案

已知该问题已上报至谷歌并标记修复,但当前版本仍存在,可尝试以下临时方案:

  • 方案1:延迟初始化SheetState
    手动创建SheetState并在布局完成后再初始化状态,避免在布局前读取未初始化的offset:

    @OptIn(ExperimentalMaterial3Api::class)
    val sheetState = rememberSheetState(skipPartiallyExpanded = true)
    LaunchedEffect(Unit) {
        // 延迟触发状态变更,确保布局完成
        sheetState.animateTo(SheetValue.Expanded)
    }
    

    随后将ModalBottomSheet的sheetState参数设置为该对象。

  • 方案2:禁用Lookahead布局
    针对API23设备,全局或局部禁用Lookahead布局,避免布局阶段提前读取状态:
    在Activity的onCreate中添加:

    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
        // 禁用Lookahead布局
        CompositionLocalProvider(LocalLookaheadLayoutScope provides null) {
            // 你的Compose内容
        }
    }
    
  • 方案3:降级Compose依赖版本
    暂时回退到compose-bom:2024.04.00或更早版本,该问题在旧版本中未出现。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:34:50