Blog Infos
Author
Published
Topics
,
Published
Topics
,
ViewModel
class MainActivityViewModel : ViewModel() {
private val _counterLiveData = MutableLiveData(0)
val counterLiveData: LiveData<Int> = _counterLiveData
fun incrementByOne() {
_counterLiveData.value = _counterLiveData.value?.plus(1)
}
}

2. Now we will declare an instance of ViewModel in our Fragment. Now many of you, who are new to this concept of ViewModels might be wondering, as ViewModel is just a class, we can simply declare an instance of the ViewModel and access public variables in our Activity/Fragment.
Something like -:

val viewModel = MainActivityViewModel()
findViewById<Button>(R.id.btn_increment).setOnClickListener {
viewModel.incrementByOne()
}
viewModel.counterLiveData.observe(this) { counter ->
findViewById<TextView>(R.id.tv_counter).text = "$counter"
}

Cool and easy right? NOOO. This will not throw an error, but it will not fill our purpose of retaining counter value on configuration changes. That’s not how ViewModel works. We need something called a ViewModelProvider to create a ViewModel. The correct way to create a ViewModel is -:

val viewModel = ViewModelProvider(this)[MainActivityViewModel::class.java]
findViewById<Button>(R.id.btn_increment).setOnClickListener {
viewModel.incrementByOne()
}
viewModel.counterLiveData.observe(this) { counter ->
findViewById<TextView>(R.id.tv_counter).text = "$counter"
}

Job Offers

Job Offers


    Android Developer

    Small and Modern GmbH
    Hamburg, Remote (Germany)
    • Full Time
    apply now

    Senior Android Developer (Remote)

    Komoot
    Europe
    • Full Time
    apply now

    Android Build Engineer

    Pinterest
    San Francisco, CA | Seattle, WA
    • Full Time
    apply now
Load more listings

OUR VIDEO RECOMMENDATION

, ,

‘Nitrogenize’ your project with Mvvm, Compose, UTP – A killer combination for successful deliveries

Compose took on the table a new approach to developing in Android. Besides this great new framework, large portions of our apps won’t change at all, and Unidirectional Data Flow best practices should be used
Watch Video

Jobs

ViewModelProvider
1. Activity lifecycle on Configuration changes
2. ViewModelProvider not destroyed by configuration change??????
public constructor(
owner: ViewModelStoreOwner
) : this(owner.viewModelStore, defaultFactory(owner))

Here you can see that we pass something called ViewModelStoreOwner. But in our Activity, we pass this while instantiating our ViewModelProvider.

ViewModelProvider(this)[MainActivityViewModel::class.java]

But from where did this ViewModelStoreOwner come from in our Activity? If we check the source code of Activity class, it can be noticed that the Activity class implements the ViewModelStoreOwner interface.

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        ContextAware,
        LifecycleOwner,
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner,
        ActivityResultRegistryOwner,
        ActivityResultCaller
public interface ViewModelStoreOwner {
    /**
     * Returns owned {@link ViewModelStore}
     *
     * @return a {@code ViewModelStore}
     */
    @NonNull
    ViewModelStore getViewModelStore();
}

Let’s dig further deep into the implementation of the getViewModelStore()in our Activity and see what it does.

@NonNull
@Override
public ViewModelStore getViewModelStore() {
    if (getApplication() == null) {
        throw new IllegalStateException("Your activity is not yet attached to the "
                + "Application instance. You can't request ViewModel before onCreate call.");
    }
    ensureViewModelStore();
    return mViewModelStore;
}

If the activity is not created, it returns throwing an error, but if it is it called the ensureViewModelStore() method.

void ensureViewModelStore() {
    if (mViewModelStore == null) {
        NonConfigurationInstances nc =
                (NonConfigurationInstances) getLastNonConfigurationInstance();
        if (nc != null) {
            // Restore the ViewModelStore from NonConfigurationInstances
            mViewModelStore = nc.viewModelStore;
        }
        if (mViewModelStore == null) {
            mViewModelStore = new ViewModelStore();
        }
    }
}
if (nc != null) {
            // Restore the ViewModelStore from NonConfigurationInstances
            mViewModelStore = nc.viewModelStore;
        }
static final class NonConfigurationInstances {
    Object custom;
    ViewModelStore viewModelStore;
}
getLifecycle().addObserver(new LifecycleEventObserver() {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        if (event == Lifecycle.Event.ON_DESTROY) {
            // Clear out the available context
            mContextAwareHelper.clearAvailableContext();
            // And clear the ViewModelStore
            if (!isChangingConfigurations()) {
                getViewModelStore().clear();
            }
        }
    }
});

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Three years ago I wrote an article about binding a list of items to…
READ MORE

Leave a Reply

Your email address will not be published.

Fill out this field
Fill out this field
Please enter a valid email address.

Menu