Android LiveData - 如何在不同的活动上重用相同的ViewModel?

use*_*216 17 java android android-livedata

示例ViewModel:

public class NameViewModel extends ViewModel {
    // Create a LiveData with a String
    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<>();
        }
        return mCurrentName;
    }

}
Run Code Online (Sandbox Code Playgroud)

主要活动:

mModel = ViewModelProviders.of(this).get(NameViewModel.class);

// Create the observer which updates the UI.
final Observer<String> nameObserver = textView::setText;

// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
mModel.getCurrentName().observe(this, nameObserver);
Run Code Online (Sandbox Code Playgroud)

我想调用mModel.getCurrentName().setValue(anotherName);第二个活动并使MainActivity接收更改.那可能吗?

Sae*_*umi 32

当你调用时ViewModelProviders.of(this),你实际上创建/保留了一个ViewModelStore绑定的this,所以不同的Activities有不同的ViewModelStore,每个使用给定的工厂ViewModelStore创建一个不同的实例ViewModel,所以你不能ViewModel在不同的ViewModelStores中拥有相同的a实例.

但是,您可以通过传递充当单件工厂的自定义ViewModel工厂的单个实例来实现此目的,因此它将始终传递您ViewModel在不同活动中的相同实例.

例如:

public class SingletonNameViewModelFactory extends ViewModelProvider.NewInstanceFactory {


    NameViewModel t;

    public SingletonNameViewModelFactory() {
      //  t = provideNameViewModelSomeHowUsingDependencyInjection
    }

    @Override
    public NameViewModel create(Class<NameViewModel> modelClass) {
        return t;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你需要的是制作SingletonNameViewModelFactory单例(例如使用Dagger)并像这样使用它:

mModel = ViewModelProviders.of(this,myFactory).get(NameViewModel.class);
Run Code Online (Sandbox Code Playgroud)

注意:

ViewModel在不同范围之间保留s是反模式.强烈建议保留您的数据层对象(例如,使您的DataSource或Repository单例)并在不同的范围(活动)之间保留您的数据.

阅读文章的详细信息.

  • 如果您已经在单例数据层中缓存数据,那么 ViewModel 的意义何在? (3认同)

Tot*_*ian 10

使用ViewModelProviders获取视图模型时,您将作为生命周期所有者传递MainActivity,这将为该活动提供视图模型.在第二个活动中,您将获得该ViewModel的不同实例,这次是您的第二个活动.第二个模型将有第二个实时数据.

您可以做的是将数据保存在不同的层中,例如存储库,它可以是单例,这样您就可以使用相同的视图模型.

在此输入图像描述

public class NameViewModel extends ViewModel {
    // Create a LiveData with a String
    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = DataRepository.getInstance().getCurrentName();
        }
        return mCurrentName;
    }
}

//SingleTon
public class DataRepository     

    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<>();
        }
        return mCurrentName;
    }
//Singleton code
...
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是一个可接受的答案..不违反 android 架构模式 (3认同)
  • 在本官方教程中[此处](https://medium.com/androiddevelopers/viewmodels-and-livedata-patterns-antipatterns-21efaef74a54)也推荐这种方法:`存储库中的LiveData:为了避免泄漏ViewModels和回调地狱,存储库可以观察到` (2认同)