54

In Dagger Hilt View Model 1.0.0-alpha01

    implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01"
    implementation 'com.google.dagger:hilt-android:2.28-alpha'
    kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
    kapt 'com.google.dagger:hilt-android-compiler:2.28-alpha'

I can use the below

class MyViewModel @ViewModelInject constructor(
    private val repository: Repository,
    @Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel(), LifecycleObserver {

    // Some codes...
}

However, when I migrate to Dagger Hilt View Model 1.0.0-alpha03

    implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
    implementation 'com.google.dagger:hilt-android:2.31.2-alpha'
    kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
    kapt 'com.google.dagger:hilt-android-compiler:2.31.2-alpha'

I got the warnings

'Assisted' is deprecated. Deprecated in Java
'ViewModelInject' is deprecated. Deprecated in Java
'ViewModelInject' is deprecated. Deprecated in Java
'Assisted' is deprecated. Deprecated in Java

What's the new way of working on it?

Elye
  • 53,639
  • 54
  • 212
  • 474

5 Answers5

107

In alpha03, Use the new @HiltViewModel and the normal @Inject now as shown below.

@HiltViewModel
class MyViewModel @Inject constructor(
    private val repository: Repository,
    private val savedStateHandle: SavedStateHandle
) : ViewModel(), LifecycleObserver {

    // Some code
}
Elye
  • 53,639
  • 54
  • 212
  • 474
  • what if we want to pass string from fragment to ViewModel's constructor and also inject repositories – Daniyal Javaid May 10 '21 at 13:59
  • @DaniyalJavaid I think that there are only two ways. 1) **Use a SavedStateHandle** as your container of fragment arguments (just like in the answer). 2) Create **your own AssistedFactory**. – Daniil Pavlenko May 16 '21 at 14:14
  • can we use private parameters? sometimes I get "cannot be final" errors. – Amg91 Dec 10 '21 at 04:24
  • My project has hundrets of Fragments in the form MyFragment : BaseFragment(R.layout.my_layoyut), where the BaseFragment's constructor has some optional parameters, how to migrate this from dagger to hilt? – David Dec 24 '22 at 23:35
51

In the last update of dagger hilt, they made few changes, so in your case, you can use @HiltViewModel and @Inject to use it with ViewModel.

@HiltViewModel
class MyViewModel @Inject constructor(
    private val repository: Repository,
    private val savedStateHandle: SavedStateHandle
) : ViewModel(), LifecycleObserver {
    // Some codes...
}

Also, if you were using ApplicationComponent, in the latest update it is changed to SingletonComponent.
So in your module class this way.

@Module
@InstallIn(SingletonComponent::class.java)
object hiltmodel....{}
Abhimanyu
  • 11,351
  • 7
  • 51
  • 121
Taki
  • 3,290
  • 1
  • 16
  • 41
  • 1
    Please look up at the documentation again. Your examples are wrong. @HiltViewModelInject is not needed anymore, as it is deprecated. – Andrew Feb 14 '21 at 11:36
  • 2
    Are you sure ? cause we only used to add ViewModelInject but in the latest version we use HiltViewModel along with Inject for viewmodel class constructor – Taki Feb 14 '21 at 15:06
  • @Andrew take a look here , https://dagger.dev/hilt/view-model – Taki Feb 14 '21 at 15:11
  • 1
    Well maybe you should look at your own link. As you can clearly see, your example is wrong! '@Assisted' is no longer needed in front of savedstatehandle and it should be '@HiltViewModel' and not '@HiltViewModelInject' like you wrote.. – Andrew Feb 14 '21 at 15:26
  • 1
    @Andrew thank you for the clarification , clearly was my bad , appreciated the correction – Taki Feb 14 '21 at 16:09
  • This is an awesome answer. I recently upgraded an old project and this answer saved my day. – Taslim Oseni Aug 30 '21 at 20:11
8

@ViewModelInject has been deprecated and has been replaced by @HiltViewModel.

The ViewModel annotated with HiltViewModel will be available for creation by HiltViewModelFactory. The HiltViewModel containing a constructor annotated with Inject will have its dependencies defined in the constructor parameters injected by Dagger's Hilt. https://dagger.dev/api/latest/dagger/hilt/android/lifecycle/HiltViewModel

A simple ViewModel will now look like :

@HiltViewModel
class MainViewModel @Inject constructor(application: Application) :
AndroidViewModel(application) {
}

or

@HiltViewModel
class MainViewModel @Inject constructor() :
ViewModel() {
}

whatever your use case might be.
Anubhav
  • 1,984
  • 22
  • 17
1

Got below error after upgrading hilt to v2.31+ ?:

2021-04-02 20:05:22.443 3718-3718/com.demo.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.demo.app, PID: 3718
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.demo.app/com.demo.app.ux.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.demo.app.ux.viewmodels.MainViewModel
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) .....

Tried most of things mentioned in here and also adding a seperate module with model view provider API, but that none of that worked one thing missed while upgrading was to change the classpath version too.

So to make this work we need to update the classpath to 2.31 and above which is present in your project gradle :

classpath "com.google.dagger:hilt-android-gradle-plugin:2.31-alpha"

releases before jan 2021 dont support the latest @HiltViewModel annotation.

MDT
  • 1,535
  • 3
  • 16
  • 29
0

So in the project level gradle in dependencies replace hilt version to 2.33-beta

buildscript{
    ext.hiltVersion = "2.33-beta"
    dependencies{
        classpath "com.google.dagger:hilt-android-gradle-plugin:$hiltVersion"
    }
}

and in the view model class instead of @viewmodelinject before constructor remove that and do this

@HiltViewModel
class TasksViewModel @Inject constructor(val taskDao: TaskDao) : ViewModel() {...}
shekhar g h
  • 1,193
  • 1
  • 9
  • 12