0

I have stepped through the Android Room with a View - Java codelab and wound up with an error that causes the app to crash before it loads (see "fatal exception", below). Thinking perhaps I did something wrong, I copied the contents of each of the .java solution files from github.

I tried creating overloading the WordViewModel class with another constructor that took no arguments, but that only created more issues.

public WordViewModel( ) {
    super(new Application());
    mRepository = new WordRepository(new Application());
    mAllWords = mRepository.getAllWords();
}

Fatal Exception:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.roomwordssample, PID: 32145
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.roomwordssample/com.example.android.roomwordssample.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.android.roomwordssample.WordViewModel
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
 Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.android.roomwordssample.WordViewModel
    at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
    at com.example.android.roomwordssample.MainActivity.onCreate(MainActivity.java:32)
    at android.app.Activity.performCreate(Activity.java:8000)
    at android.app.Activity.performCreate(Activity.java:7984)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7656) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
 Caused by: java.lang.InstantiationException: java.lang.Class<com.example.android.roomwordssample.WordViewModel> has no zero argument constructor
    at java.lang.Class.newInstance(Native Method)
    at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187) 
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
    at com.example.android.roomwordssample.MainActivity.onCreate(MainActivity.java:32) 
    at android.app.Activity.performCreate(Activity.java:8000) 
    at android.app.Activity.performCreate(Activity.java:7984) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7656) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

Any ideas what could be triggering this?

Update: Also tried copying the app and project build.gradle files over from the solutions on github. To let it compile I had to change the minSdkVersion to 21 (from 20) to resolve a build error regarding vector graphics. Also changed the dependency to gradle version 4.1.0 (from 3.4.3 in the solution). Compiles, but running the app triggers the same error as above.

Update #2 Also tried copying over gradle-wrapper.properties (which references gradle-5.1.1-all distribution) and restoring the buid.gradle to the solution's version (which references Gradle plugin version 3.4.3). Still no dice.

Update #3 I downloaded the entire solution project from GitHub and imported it into a new project in Android Studio. It compiles but generates the exact same no zero argument constructor error.

CragMonkey
  • 808
  • 1
  • 11
  • 22
  • Either you need to have viewmodelfactory class or pass the param to viewmodel. please this link. https://stackoverflow.com/questions/54419236/why-a-viewmodel-factory-is-needed-in-android – Rushit Vaishnani Nov 11 '20 at 13:41

2 Answers2

0

Found a fix posted on the GitHub issues tab for this project which resolved this for me: Simply open MainActivity.java and within onCreate, find:

mWordViewModel = new ViewModelProvider(this).get(WordViewModel.class)

And change it to:

mWordViewModel = new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(WordViewModel.class);
CragMonkey
  • 808
  • 1
  • 11
  • 22
0

By default viewModel accepts zero args which mean there will be no arguments in the viewModel just an empty constructor
But if you wanna pass something in the viewModel constructor.
There are two ways:
1-> AndroidViewModel: Which accepts only one type of arg and it is applicationContext

class MainViewModel(application: Application): AndroidViewModel(application) {}

Remember: no other value can be passed in constructor args when you are using androidViewModel

2-> ViewModelFactory: You will be using regular viewModel but you are making extra viewModelFactory class:
here is complete implementation of viewModelFactory:
ViewModel

class MainViewModel(val value: Int): ViewModel() {}

ViewModelFactory:

  class ViewModelFactory(
       private val value: Int     
        ): ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(MainViewModel::class.java)){
                return MainViewModel(value) as T
            }
            throw IllegalArgumentException("Invalid model class")
        }
    }

Your Activity:

lateinit var viewModel : MainViewModel
private val viewModelFactory: ViewModelProvider.Factory = ViewModelFactory(10)

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 viewModel = ViewModelProvider(this, viewModelFactory)[MainViewModel::class.java]
}


USMAN osman
  • 952
  • 7
  • 13