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

Android LiveData:如何在不同Activity中复用同一个ViewModel?

在Android不同Activity中复用同一个ViewModel的实现方案

默认情况下,我们用ViewModelProviders.of(this)(或新版ViewModelProvider(this))获取ViewModel时,每个Activity都会拿到独立的实例——因为每个Activity都有自己的ViewModelStore,ViewModel会和宿主的生命周期绑定。要在多个Activity间复用同一个ViewModel,核心思路是让它们共享同一个ViewModelStoreOwner,下面给两种实用的实现方式:

方法一:以Application作为ViewModelStoreOwner(官方推荐)

Application是全局唯一的组件,它的生命周期和整个应用一致,用它作为ViewModel的宿主,所有Activity通过它获取的ViewModel都会是同一个实例。

步骤示例

  1. 你的NameViewModel代码保持不变:
public class NameViewModel extends ViewModel {
    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<>();
        }
        return mCurrentName;
    }
}
  1. 主Activity中获取ViewModel并观察:
// 关键:把this换成getApplication(),用Application作为宿主
NameViewModel mModel = new ViewModelProvider(getApplication()).get(NameViewModel.class);

// 创建UI观察者
final Observer<String> nameObserver = textView::setText;
// 观察LiveData,Activity销毁时会自动移除观察者
mModel.getCurrentName().observe(this, nameObserver);

// 示例:点击按钮更新LiveData值
updateBtn.setOnClickListener(v -> {
    mModel.getCurrentName().setValue("来自主Activity的新名字");
});
  1. 第二个Activity中复用同一个ViewModel:
// 同样用getApplication()获取ViewModel实例
NameViewModel sharedModel = new ViewModelProvider(getApplication()).get(NameViewModel.class);

// 观察LiveData,当主Activity更新值时,这里的UI会同步刷新
sharedModel.getCurrentName().observe(this, newName -> {
    secondActivityTextView.setText(newName);
});

这种方式不需要额外写单例代码,符合Jetpack的设计规范,是最省心的方案。

方法二:自定义单例ViewModelStoreOwner(适用于特定页面组共享)

如果你只想在某几个特定Activity间共享ViewModel,且希望这些页面全部销毁后自动清理ViewModel(避免和应用生命周期绑定导致的内存占用),可以自定义一个单例的ViewModelStoreOwner:

步骤示例

  1. 实现单例的ViewModelStoreOwner:
public class SharedViewModelStoreOwner implements ViewModelStoreOwner {
    // 单例实例
    private static final SharedViewModelStoreOwner INSTANCE = new SharedViewModelStoreOwner();
    private final ViewModelStore viewModelStore = new ViewModelStore();

    // 私有构造方法防止实例化
    private SharedViewModelStoreOwner() {}

    public static SharedViewModelStoreOwner getInstance() {
        return INSTANCE;
    }

    @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        return viewModelStore;
    }

    // 手动清理方法:在最后一个共享Activity销毁时调用,避免内存泄漏
    public void clearViewModelStore() {
        viewModelStore.clear();
    }
}
  1. 在Activity中获取ViewModel:
// 用自定义的单例Owner获取ViewModel
NameViewModel mModel = new ViewModelProvider(SharedViewModelStoreOwner.getInstance()).get(NameViewModel.class);

// 后续的观察、更新逻辑和方法一一致
  1. 记得在合适的时机清理:比如在最后一个共享Activity的onDestroy()中调用SharedViewModelStoreOwner.getInstance().clearViewModelStore();

注意事项

  • 用Application作为宿主时,ViewModel的生命周期和应用一致,如果ViewModel持有大对象或资源,要注意在不需要时手动清理数据,避免内存泄漏。
  • LiveData的observe()方法会自动感知Activity的生命周期,当Activity处于销毁状态时,会自动移除观察者,不用担心内存泄漏问题。
  • 如果你用Kotlin开发,代码会更简洁,比如val model = ViewModelProvider(application).get(NameViewModel::class.java)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:21:23