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
相关产品推荐
相关产品推荐

