使用 Hilt 注入 viewModel 时不调用 init

init is not called when injecting viewModel using Hilt

我想在初始化 ViewModel 时发出 API 请求。这就是为什么我在 init 方法中发出 API 请求;当我在 Activity 中注入 viewModel 时,期望 init 被触发。我做错了什么?

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)
    }
}

您误解了注入委托。

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

这不是 dagger/hilt 注入。这是对 AndroidKTX 提供的惰性委托的调用。所以你得到的行为是预期的,当你第一次访问 属性 mainViewModel 时,你的 ViewModel 将被创建(而不是注入)。所以你的 init {} 块的时间是预期的。

来自 Dagger/Hilt 的文档 (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.

您可以做的是在您的 onCreate 方法中访问 mainViewModel,这将尽可能早地触发 init 块。 或者删除委托并手动初始化 onCreate 中的 mainViewModel

mainViewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)