Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

init is not called when injecting viewModel using Hilt

I want to make API request when ViewModel is initialized. That`s why I make API request inside init method; expecting init be triggered when I inject viewModel in Activity. What am I doing wrong?

MainViewModel.kt

@HiltViewModel
class MainViewModel @Inject constructor(private val mainRepository: MainRepo) : ViewModel() {
companion object {
    var TAG = "MainViewModel**"
}

init {
    Log.d(TAG, "NOT TRIGGERED: ")

    viewModelScope.launch {
        val album1: List<AlbumItem> = mainRepository.getAlbums()
    }
}}

MainActivity.kt

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private val mainViewModel : MainViewModel by viewModels() // injecting viewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityMainBinding =
            DataBindingUtil.setContentView(this, R.layout.activity_main)
    }
}
like image 763
Yunis Rasulzade Avatar asked May 12 '26 19:05

Yunis Rasulzade


1 Answers

You are misunderstanding a delegate for injection.

private val mainViewModel : MainViewModel by viewModels() // injecting viewModel (Wrong)

This is not dagger/hilt injection. This is a call to lazy delegate provided by AndroidKTX. So the behavior you are getting is expected, your ViewModel will be created (not injected) when you first access the property mainViewModel. So the timing of your init {} block is expected.

From Dagger/Hilt's documentation (https://dagger.dev/hilt/view-model.html)

Warning: Even though the view model has an @Inject constructor, it is an error to request it from Dagger directly (for example, via field injection) since that would result in multiple instances. View Models must be retrieved through the ViewModelProvider API. This is checked at compile time by Hilt.

What you can do is access mainViewModel in your onCreate method and that will trigger the init block early as possible. Or remove the delegate and initialize mainViewModel in onCreate manually.

mainViewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
like image 199
Muhammad Faiq Avatar answered May 14 '26 09:05

Muhammad Faiq



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!