Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

}

Main activity:

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

I want to call mModel.getCurrentName().setValue(anotherName); in second activity and make MainActivity receive changes. Is that possible?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
285 views
Welcome To Ask or Share your Answers For Others

1 Answer

When you call ViewModelProviders.of(this), you actually create/retain a ViewModelStore which is bound to this, so different Activities have different ViewModelStore and each ViewModelStore creates a different instance of a ViewModel using a given factory, so you can not have the same instance of a ViewModel in different ViewModelStores.

But you can achieve this by passing a single instance of a custom ViewModel factory which acts as a singleton factory, so it will always pass the same instance of your ViewModel among different activities.

For example:

public class SingletonNameViewModelFactory extends ViewModelProvider.NewInstanceFactory {


    NameViewModel t;

    public SingletonNameViewModelFactory() {
      //  t = provideNameViewModelSomeHowUsingDependencyInjection
    }

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

So what you need is to make SingletonNameViewModelFactory singleton (e.g. using Dagger) and use it like this:

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

Note:

Preserving ViewModels among different scopes is an anti-pattern. It's highly recommended to preserve your data-layer objects (e.g. make your DataSource or Repository singleton) and retain your data between different scopes (Activities).

Read this article for details.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...