Android开发:如何在继承AndroidViewModel的类中使用SavedStateHandle保存与恢复实例状态?
没问题,我帮你解决这个问题——当继承AndroidViewModel时,确实不能直接在构造函数里传入SavedStateHandle,但我们可以通过AbstractSavedStateViewModelFactory来实现两者的结合,既保留AndroidViewModel的Application上下文,又能使用SavedStateHandle管理状态。下面是具体的修改步骤:
1. 修改MainViewModel的构造函数
让它同时接收Application和SavedStateHandle参数,同时完成状态的初始化与恢复:
public class MainViewModel extends AndroidViewModel { private static final String SAVED_KEY_STARTED = "started"; private final MutableLiveData<Boolean> isStarted; private final SavedStateHandle savedStateHandle; // 同时接收Application和SavedStateHandle public MainViewModel(Application application, SavedStateHandle savedStateHandle) { super(application); this.savedStateHandle = savedStateHandle; // 优先从SavedStateHandle恢复状态,无数据则用默认值false Boolean savedStartedState = savedStateHandle.get(SAVED_KEY_STARTED); isStarted = new MutableLiveData<>(savedStartedState != null ? savedStartedState : Boolean.FALSE); } // 示例:更新状态并同步到SavedStateHandle public void setStarted(boolean started) { isStarted.setValue(started); savedStateHandle.set(SAVED_KEY_STARTED, started); } public LiveData<Boolean> getIsStarted() { return isStarted; } // 这里可以添加仓库相关操作,用getApplication()获取上下文 }
2. 替换ViewModelFactory为AbstractSavedStateViewModelFactory
原来的AndroidViewModelFactory只能提供Application,我们需要用AbstractSavedStateViewModelFactory来同时生成Application和SavedStateHandle。修改你在Fragment中获取ViewModel的代码:
viewModel = new ViewModelProvider(this, new AbstractSavedStateViewModelFactory(this, getArguments()) { @NonNull @Override protected <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass, @NonNull SavedStateHandle handle) { // 传入Application和SavedStateHandle创建ViewModel实例 return (T) new MainViewModel(requireActivity().getApplication(), handle); } }).get(MainViewModel.class);
关键说明
AbstractSavedStateViewModelFactory需要接收SavedStateRegistryOwner(这里Fragment本身就是,所以传this)和可选的初始化参数(getArguments()),它会负责创建和管理SavedStateHandle的生命周期。- 在
create方法中,我们手动实例化MainViewModel,把Application和生成的SavedStateHandle传进去,这样就同时满足了AndroidViewModel的上下文需求和状态保存需求。 - 每次更新状态时,记得同步调用
savedStateHandle.set(),这样状态会在配置变更或进程被杀后自动恢复。
这样修改后,你的MainViewModel既能通过getApplication()获取上下文用于仓库操作,又能像之前一样用SavedStateHandle管理实例状态了。
内容的提问来源于stack exchange,提问作者Teo Shi Bin
相关产品推荐
相关产品推荐

