Home > Net >  Cannot create an instance of class com.example.retrotest.ui.AlbumsViewModel
Cannot create an instance of class com.example.retrotest.ui.AlbumsViewModel

Time:04-04

Got a error when I try to launch the app with the emulator. Try to look up the AlbumListFragment errors at line: 40 and 41. I can't understand what I have done wrong. Have implemented this code severals times without errors.

I also use android:text="@{viewModel.response}" inside the fragment layout. I don't think databinding is the problem.

Anyone see what I do wrong?

2022-04-03 18:25:22.687 4959-4959/com.example.mvvmretrofit E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mvvmretrofit, PID: 4959
    java.lang.RuntimeException: Cannot create an instance of class com.example.retrotest.ui.AlbumsViewModel
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:230)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:169)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139)
        at com.example.retrotest.ui.AlbumListFragment$onCreateView$viewModel$2.invoke(AlbumListFragment.kt:41)
        at com.example.retrotest.ui.AlbumListFragment$onCreateView$viewModel$2.invoke(AlbumListFragment.kt:40)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at com.example.retrotest.ui.AlbumListFragment.onCreateView$lambda-0(AlbumListFragment.kt:40)
        at com.example.retrotest.ui.AlbumListFragment.onCreateView(AlbumListFragment.kt:43)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2995)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
        at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777)
        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841)
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
        at android.app.Activity.performStart(Activity.java:8018)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        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.NoSuchMethodException: com.example.retrotest.ui.AlbumsViewModel.<init> [class android.app.Application]
        at java.lang.Class.getConstructor0(Class.java:2332)
        at java.lang.Class.getConstructor(Class.java:1728)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:228)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:169) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139) 
        at com.example.retrotest.ui.AlbumListFragment$onCreateView$viewModel$2.invoke(AlbumListFragment.kt:41) 
        at com.example.retrotest.ui.AlbumListFragment$onCreateView$viewModel$2.invoke(AlbumListFragment.kt:40) 
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) 
        at com.example.retrotest.ui.AlbumListFragment.onCreateView$lambda-0(AlbumListFragment.kt:40) 
        at com.example.retrotest.ui.AlbumListFragment.onCreateView(AlbumListFragment.kt:43) 
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2995) 
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523) 
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) 
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374) 
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841) 
        at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777) 
        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020) 
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551) 
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) 
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374) 
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841) 
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784) 
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262) 
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478) 
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246) 
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435) 
        at android.app.Activity.performStart(Activity.java:8018) 
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475) 
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) 
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        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) 
2022-04-03 18:25:23.849 4959-4975/com.example.mvvmretrofit W/System: A resource failed to call close. 

AlbumListFragment:

class AlbumListFragment : Fragment() {

    private val viewModel: AlbumsViewModel by lazy {
        ViewModelProvider(this)[AlbumsViewModel::class.java]
    }
    /**
     * Inflates the layout with Data Binding, sets its lifecycle owner to the OverviewFragment
     * to enable Data Binding to observe LiveData, and sets up the RecyclerView with an adapter.
     */
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding = FragmentAlbumListBinding.inflate(inflater)

        binding.viewModel = viewModel

        // Allows Data Binding to Observe LiveData with the lifecycle of this Fragment
        binding.lifecycleOwner = this

        // Giving the binding access to the OverviewViewModel
        binding.viewModel = viewModel

        setHasOptionsMenu(true)
        return binding.root
    }

    /**
     * Inflates the overflow menu that contains filtering options.
     */
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.overflow_menu, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }
}

AlbumsViewModel.kt:

class AlbumsViewModel(val application: MyApplication) : AndroidViewModel(application) {

    private val _response = MutableLiveData<String>()

    val response: LiveData<String>
        get() = _response

    /**
     * Call getMarsRealEstateProperties() on init so we can display status immediately.
     */
    init {
        getAlbumProperties()
    }

    /**
     * Sets the value of the status LiveData to the Mars API status.
     */
    private fun getAlbumProperties() {
        AlbumApi.retrofitService.getAllAlbums().enqueue(object: Callback<List<Album>> {

            override fun onResponse(call: Call<List<Album>>, response: Response<List<Album>>) {
                _response.value = "Success: ${response.body()?.size} Album properties retrieved"
            }

            override fun onFailure(call: Call<List<Album>>, t: Throwable) {
                _response.value = "Failure: "   t.message
            }

        })
        _response.value = "Set the Album API Response here!"
    }

}

CodePudding user response:

The real error is the one listed lower down

Caused by: java.lang.NoSuchMethodException: com.example.retrotest.ui.AlbumsViewModel.<init> [class android.app.Application]

This error is because your ViewModel has a non-standard constructor (uses your custom MyApplication instead of the default Application argument) and the provider factory can't find the constructor it is looking for.

You need to change

AlbumsViewModel(val application: MyApplication)

to

AlbumsViewModel(val application: Application)

to get it to work.

If you actually need an instance of MyApplication in your ViewModel somwewhere you can always get it by having it cast from the base class like this:

val myapp = getApplication<MyApplication>()
  • Related