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

Android/Kotlin:屏幕旋转时全局变量能否可靠存状态?替代Bundle是否为不良实践?

Android屏幕旋转时全局变量的状态保留问题

1. 能否信任全局变量在屏幕旋转时始终保留状态?

多数常规测试场景下,屏幕旋转时全局变量不会被重置,但绝对不能“始终信任”这种行为:

  • 屏幕旋转默认触发Activity重建,但全局变量(比如你代码里的顶级属性)属于App进程的内存区域,只要进程未被系统杀死,变量状态就会保留。你测试中没出现异常,是因为测试时进程一直处于存活状态。
  • 但当系统内存紧张时,会主动杀死后台的App进程。此时用户旋转屏幕重新打开App,进程会重启,全局变量会被重新初始化(回到初始空列表状态),这种场景在真实用户环境中是可能发生的。

2. 用全局变量替代Bundle保存旋转状态是否属于不良实践?

属于明确的不良实践,核心隐患包括:

  • 进程被杀导致状态丢失:系统回收内存杀死进程后,全局变量的状态会完全丢失;而Bundle是与Activity实例绑定的,系统会在杀死进程前自动保存Bundle,重启时能恢复状态。
  • 状态与生命周期脱节:全局变量是进程级的,不受Activity生命周期控制。比如用户打开多个Activity实例、切换到其他App再返回时,全局变量的状态可能与当前Activity的预期逻辑冲突,引发混乱。
  • 内存泄漏风险:如果全局变量持有Context或Activity的引用,会导致这些组件无法被GC回收,进而引发内存泄漏——因为进程级变量的生命周期远长于单个Activity。
  • 可维护性差:全局变量的状态变化难以追踪,多个组件修改同一全局变量时,极易出现难以排查的Bug;而Bundle的状态管理与Activity绑定,逻辑边界更清晰。

针对你代码的优化建议

你的场景是预加载固定关卡数据,这类静态资源可以通过Application类单例实现全局缓存,既避免重复加载,又能在进程重启时重新初始化:

class MyApp : Application() {
    val LEVEL_FILES = arrayOf("levels/lv1.txt", "levels/lv2.txt", "levels/lv3.txt")
    val LEVEL_DEFS = mutableListOf<LevelDefinition>()

    override fun onCreate() {
        super.onCreate()
        // 进程启动时仅执行一次初始化
        for (filename in LEVEL_FILES) {
            LEVEL_DEFS.add(LevelDefinition(getTextFileString(this, filename)))
        }
    }

    private fun getTextFileString(context: Context, filename: String): String {
        // 实现文件读取逻辑
    }
}

// 在Activity中获取缓存数据
val app = application as MyApp
val levels = app.LEVEL_DEFS

如果是用户动态修改的状态(比如当前关卡进度),仍需使用Bundle、ViewModel或SavedInstanceState来保存,确保进程被杀后能恢复数据。

内容的提问来源于stack exchange,提问作者Makindi.Runner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:30:50