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

2022-09-01 01:25:09

示例视图模型:

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;
    }

}

主要活动:

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);

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


答案 1

当您调用 时,您实际上创建/保留了一个绑定到 的实例,因此不同的活动具有不同,并且每个活动都使用给定的工厂创建一个不同的实例,因此您不能在不同的s中具有相同的实例。ViewModelProviders.of(this)ViewModelStorethisViewModelStoreViewModelStoreViewModelViewModelViewModelStore

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

例如:

public class SingletonNameViewModelFactory extends ViewModelProvider.NewInstanceFactory {


    NameViewModel t;

    public SingletonNameViewModelFactory() {
      //  t = provideNameViewModelSomeHowUsingDependencyInjection
    }

    @Override
    public NameViewModel create(Class<NameViewModel> modelClass) {
        return t;
    }
}

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

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

注意:

在不同作用域之间保留 s 是一种反模式。强烈建议保留数据层对象(例如,将数据源或存储库设置为单例),并在不同作用域(活动)之间保留数据。ViewModel

有关详细信息,请阅读本文


答案 2

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

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

enter image description here

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
...
}

推荐