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

Android开发:如何在屏幕旋转时保存复杂类实例状态?

解决屏幕旋转时复杂对象状态保留的可靠方案

针对你遇到的BleManager在屏幕旋转时状态丢失的问题,以下是几个比静态object更可靠的方案:

1. 使用ViewModel托管实例

ViewModel的核心特性就是跨越配置变化(如屏幕旋转)保留实例,完全适配你的场景:

  • 创建一个继承自AndroidViewModel的类,内部持有BleManager实例(使用Application Context避免内存泄漏):
    class BleViewModel(application: Application) : AndroidViewModel(application) {
        val bleManager = BleManager(application)
    }
    
  • 在Activity/Fragment中通过ViewModelProvider获取ViewModel实例:
    val viewModel = ViewModelProvider(this)[BleViewModel::class.java]
    // 直接使用viewModel.bleManager调用蓝牙逻辑
    
    屏幕旋转时ViewModel不会被销毁,BleManager的状态自然得以保留,同时彻底规避内存泄漏风险。

2. 使用依赖注入的Activity Retained作用域

如果项目使用Hilt或Dagger,可给BleManager设置ActivityRetained作用域:

  • 以Hilt为例,给BleManager添加@ActivityRetainedScoped注解,并注入Application Context:
    @ActivityRetainedScoped
    class BleManager @Inject constructor(
        @ApplicationContext private val context: Context
    ) {
        // 蓝牙相关逻辑实现
    }
    
  • 在Activity/Fragment中注入实例:
    @AndroidEntryPoint
    class MainActivity : AppCompatActivity() {
        @Inject lateinit var bleManager: BleManager
        // 业务逻辑中直接使用bleManager
    }
    
    @ActivityRetainedScoped的实例会在Activity配置变化时保留,自动管理生命周期,既解决了静态object的多实例冲突问题,也避免了内存泄漏。

3. (过时但兼容老项目)保留无UI Fragment实例

若不想使用ViewModel,可创建无UIFragment并调用setRetainInstance(true)托管BleManager:

  • 创建保留实例的Fragment:
    class BleRetainFragment : Fragment() {
        lateinit var bleManager: BleManager
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            retainInstance = true
            bleManager = BleManager(requireContext().applicationContext)
        }
    }
    
  • 在Activity中添加并获取该Fragment实例:
    private lateinit var bleRetainFragment: BleRetainFragment
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bleRetainFragment = supportFragmentManager.findFragmentByTag("BleRetain") as? BleRetainFragment ?: run {
            BleRetainFragment().also {
                supportFragmentManager.beginTransaction().add(it, "BleRetain").commit()
            }
        }
        // 使用bleRetainFragment.bleManager操作蓝牙
    }
    
    该方案已被ViewModel取代,但适配未引入Jetpack的老项目。

这些方案均能可靠保留BleManager状态,同时规避静态object的诸多弊端,适配屏幕旋转等配置变化场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:40:16