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

Fragment setRetainInstance()已废弃,对应的替代实现方案是什么?

Fragment setRetainInstance() 废弃后的状态保留方案

官方废弃setRetainInstance()的核心原因是该API容易引发内存泄漏、生命周期管理异常,推荐优先使用ViewModel实现状态留存,适配99%的原有业务场景。

前置依赖配置(Module级build.gradle的dependencies块添加)

implementation "androidx.fragment:fragment-ktx:1.6.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"

方案1:普通状态留存(配置变更时保留数据/状态不丢失)

1. 定义ViewModel存储需要保留的状态

import androidx.lifecycle.ViewModel

class HomeViewModel : ViewModel() {
    // 所有需要保留的状态、数据都存储在此处
    var userDataList: MutableList<String> = mutableListOf()
    var currentPagerPosition: Int = 0
    // 支持存储无法序列化的复杂对象、异步任务实例等
}

2. Fragment中使用ViewModel

import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import android.os.Bundle

class HomeFragment: Fragment (){
    // 通过viewModels扩展获取ViewModel实例,配置变更后重建Fragment时拿到的是同一个实例
    private val viewModel: HomeViewModel by viewModels()

     override fun onCreate(savedInstanceState: Bundle?){
          super.onCreate(savedInstanceState)
          // 不再需要写retainInstance = true
          
          if (viewModel.userDataList.isEmpty()) {
              // 首次创建Fragment时加载初始数据
              loadInitData()
          } else {
              // 配置变更后重建Fragment时直接复用已有数据
              renderUi(viewModel.userDataList, viewModel.currentPagerPosition)
          }
     }

    private fun loadInitData() {
        // 模拟数据加载逻辑
        viewModel.userDataList = mutableListOf("数据1", "数据2", "数据3")
        viewModel.currentPagerPosition = 1
        renderUi(viewModel.userDataList, viewModel.currentPagerPosition)
    }

    private fun renderUi(data: List<String>, position: Int) {
        // 此处写UI渲染逻辑
    }
}

方案2:进程杀死后也能恢复的持久化状态留存

如果需要状态在应用进程被系统主动杀死后重启也能恢复,可以配合SavedStateHandle实现:

1. 带SavedStateHandle的ViewModel

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel

class HomeViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    // 定义需要持久化保留的状态
    var currentPage: Int
        get() = savedStateHandle["CURRENT_PAGE"] ?: 0
        set(value) = savedStateHandle.set("CURRENT_PAGE", value)
    
    // 临时状态也可以正常存在ViewModel中
    var tempList: MutableList<String> = mutableListOf()
}

2. Fragment中使用方式和方案1完全一致

private val viewModel: HomeViewModel by viewModels()

注意:配置变更时Fragment本身依然会走正常的销毁重建流程,但状态全部存储在ViewModel中,重建后可以直接恢复,和原retainInstance = true的业务效果完全一致,且避免了原API可能导致的内存泄漏、生命周期异常问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:45:00