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

Jetpack Compose异常:Snapshot is not open 混淆开启时的解决方法咨询

问题分析与解决方案

异常信息

java.lang.IllegalStateException
Snapshot is not open

androidx.compose.runtime.snapshots.SnapshotKt.validateOpen(Snapshot.kt:1465)
androidx.compose.runtime.snapshots.SnapshotKt.access$validateOpen(Snapshot.kt:1)
androidx.compose.runtime.snapshots.MutableSnapshot.apply(Snapshot.kt:584)
androidx.compose.runtime.Recomposer.applyAndCheck(Recomposer.kt:822)
androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1092)
androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:105)
androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:456)
androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:425)
androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
android.view.Choreographer$CallbackRecord.run(Choreographer.java:856)
android.view.Choreographer.doCallbacks(Choreographer.java:670)
android.view.Choreographer.doFrame(Choreographer.java:603)
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
android.os.Handler.handleCallback(Handler.java:739)
android.os.Handler.dispatchMessage(Handler.java:95)
android.os.Looper.loop(Looper.java:148)
android.app.ActivityThread.main(ActivityThread.java:5647)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)

该异常发生在MuMu模拟器,Android版本6.0.1。关闭混淆(minifyEnabled false)可解决,但使用-keep public class androidx.compose.*.**{*; }无法修复,需找到开启混淆时的有效修复方案。

修复方案

自定义的ProGuard规则不够精准是问题根源,Compose运行时依赖大量内部类、合成函数和快照相关特性,宽泛的keep规则无法覆盖所有必要部分。需添加以下针对性规则到proguard-rules.pro文件中:

1. 保留快照核心逻辑相关类与成员

# 保留快照验证与应用逻辑的核心类和方法
-keep class androidx.compose.runtime.snapshots.** { *; }
-keepclassmembers class androidx.compose.runtime.snapshots.SnapshotKt {
    <methods>;
}
-keepclassmembers class androidx.compose.runtime.snapshots.MutableSnapshot {
    public void apply(...);
}

2. 保留重组器关键实现

# 保留Recomposer的核心方法与内部类
-keep class androidx.compose.runtime.Recomposer { *; }
-keepclassmembers class androidx.compose.runtime.Recomposer$* { *; }

3. 保留UI线程调度相关类

# 保留Android UI时钟与调度器的完整实现
-keep class androidx.compose.ui.platform.AndroidUiFrameClock { *; }
-keep class androidx.compose.ui.platform.AndroidUiDispatcher { *; }
-keepclassmembers class androidx.compose.ui.platform.AndroidUiDispatcher$* { *; }

4. 补充Compose通用混淆规则

# 保留Composable注解及合成函数
-keep @androidx.compose.runtime.Composable class * { *; }
-keepclassmembers class * {
    @androidx.compose.runtime.Composable <methods>;
}
# 保留Compose运行时核心类的所有成员
-keep class androidx.compose.runtime.** { *; }
-keepclassmembers class androidx.compose.runtime.** {
    <fields>;
    <methods>;
}

5. 兼容Android 6.0配置

Android 6.0(API 23)对Java 8特性支持有限,需在build.gradle中添加以下配置确保兼容性:

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

原理说明

Compose的快照系统依赖大量内部私有方法和类管理状态更新,混淆时若这些成员被移除或重命名,会触发Snapshot is not open异常。原始规则仅保留了public类,遗漏了内部类、私有成员及合成方法,导致运行时无法正确调用快照验证逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:15:47