ViewModel cannot be instantiated in an Activity

10,449

Solution 1

You need to use the support library activity.

AppCompatActivity or FragmentActivity

Solution 2

@elmorabea's Answer was correct, but one important thing to note here is that if you have enabled AndroidX and are still getting an issue indicating that you need to pass in a fragment instead of an activity, make sure that your class extends the correct AppCompatActivity. IE, make sure you are using:

import androidx.appcompat.app.AppCompatActivity;

and not

import android.support.v7.app.AppCompatActivity;

As one is from AndroidX while the other is not. For more info on the AndroidX migrations, see this link.

Solution 3

You are extending Activity. ViewModelProviders works with FragmentActivity and things that inherit from that, such as AppCompatActivity. It also works with the backport of Fragment (android.support.v4.app.Fragment). There is no official support for the native Activity or Fragment class.

Solution 4

Another solution if you don't want to change your activity to extend from another Activity class (in case your BaseActivity is already used and rely heavily on Activity and maybe cause an error if change the parent activity class):

@Nullable
private ViewModelStore viewModelStore = null;

@Override
public Object onRetainNonConfigurationInstance() {
    return viewModelStore;
}

@NonNull
private ViewModelStore getViewModelStore() {
    Object nonConfigurationInstance = getLastNonConfigurationInstance();
    if (nonConfigurationInstance instanceof ViewModelStore) {
        viewModelStore = (ViewModelStore) nonConfigurationInstance;
    }
    if (viewModelStore == null) {
        viewModelStore = new ViewModelStore();
    }
    return viewModelStore;
}

public ViewModelProvider getViewModelProvider() {
    ViewModelProvider.Factory factory =
            ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication());
    return new ViewModelProvider(getViewModelStore(), factory);
}

This logic is similar to what is in FragmentActivity

Then, instead of calling ViewModelProviders.of(this), we just need to call getViewModelProvider(). For getting Controller:

control = getViewModelProvider().get(Controller.class)

By doing this, we don't need to add android.arch.lifecycle:extensions dependency.

Solution 5

I am using this:

 LoginViewModel viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);

Ref:https://developer.android.com/topic/libraries/architecture/viewmodel#java

Share:
10,449
dude
Author by

dude

nobody you should know

Updated on July 21, 2022

Comments

  • dude
    dude almost 2 years

    I am trying to instantiate one ViewModel to use across all of my Activity(s).

    public class LaunchActivity extends Activity {
        private Controller control;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_launch);
             control = ViewModelProviders.of(this).get(Controller.class);
        }
    }
    

    but I got an error at control = ViewModelProviders.of(this) <-- stating that it cannot resolve of(this), but based on the example here by Android Developer on Implementing ViewModel; a class that extends ViewModel should be able to be instantiated on Activity, am I right?

    If what I am doing is wrong, how should I instantiate a ViewModel object for my Activity(s)? Do I have to create n number of Activity(s) with Fragment(s) since ViewModelProviders.of() only works with Fragment?

  • Mudasir Sharif
    Mudasir Sharif about 6 years
    I am extending from AppCompatActivity. But still it shows the error that "Not able to resolve ViewModelProvider.of()"
  • Dabbler
    Dabbler about 6 years
    @MudasirRao: You're missing an "s" in ViewModelProviders. If it still doesn't work, make sure your Gradle file contains the dependency, e.g. compile 'android.arch.lifecycle:extensions:1.1.1'
  • Ewald Benes
    Ewald Benes over 5 years
    You've probably imported androidx.lifecycle.ViewModelProviders instead of android.arch.lifecycle.ViewModelProviders.