Dagger Hilt 'Assisted' and 'ViewModelInject' is deprecated. in Dagger Hilt View Model 1.0.0-alpha03
Asked Answered
M

6

55

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?

Middlebuster answered 13/2, 2021 at 13:49 Comment(0)
M
112

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
}
Middlebuster answered 13/2, 2021 at 13:51 Comment(4)
what if we want to pass string from fragment to ViewModel's constructor and also inject repositoriesQuinonez
@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.Wimble
can we use private parameters? sometimes I get "cannot be final" errors.Sinaloa
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?Mccain
S
53

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....{}
Scrivenor answered 13/2, 2021 at 13:56 Comment(6)
Please look up at the documentation again. Your examples are wrong. @HiltViewModelInject is not needed anymore, as it is deprecated.Affectionate
Are you sure ? cause we only used to add ViewModelInject but in the latest version we use HiltViewModel along with Inject for viewmodel class constructorScrivenor
@Affectionate take a look here , dagger.dev/hilt/view-modelScrivenor
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..Affectionate
@Affectionate thank you for the clarification , clearly was my bad , appreciated the correctionScrivenor
This is an awesome answer. I recently upgraded an old project and this answer saved my day.Winepress
A
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.
Apsis answered 16/5, 2021 at 19:31 Comment(0)
C
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.

Conto answered 2/4, 2021 at 16:42 Comment(0)
S
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() {...}
Solitary answered 31/3, 2021 at 15:7 Comment(0)
C
0

Just in case anyone comes here in 2024, ViewModels can be delivered right inside of a Composable function like (SettingsViewModel class shall be annotated as @HiltViewModel):

val viewModel: SettingsViewModel = hiltViewModel()

after adding that kind of dependency to your graddle file:

implementation "androidx.hilt:hilt-navigation-compose:1.1.0"
Chios answered 19/1 at 4:42 Comment(1)
How do I make sure I get a single ViewModel ? Because when I go out of the screen and come back the new instance of ViewModel gets created,Delenadeleon

© 2022 - 2024 — McMap. All rights reserved.