如何使用依赖项注入在ViewModel中注入构造函数

时间:2018-06-20 13:17:54

标签: android dependency-injection dagger-2 android-architecture-components android-jetpack

我正在尝试在https://developer.android.com/jetpack/docs/guide上实现示例。这说明了tan android应用的结构。

使用相同的代码时,出现以下错误。

java.lang.Class<com.example.UserProfileViewModel> has no zero argument constructor

我可以弄清楚这个错误与

有关
viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);

当我为ViewModel编写默认的零输入构造函数时,出现以下错误。

Attempt to invoke virtual method 'void android.arch.lifecycle.LiveData.observe(android.arch.lifecycle.LifecycleOwner, android.arch.lifecycle.Observer)' on a null object reference

我不知道此错误的原因以及解决方法。

2 个答案:

答案 0 :(得分:0)

如果要在片段中为viewmodel提供构造函数作为依赖项,则可以使用另一种方法,

假设您有一个如下的viewmodel类,

class SampleViewmModel(dataManager:DataManager):ViewModel(){
  //some logic
}

然后,您需要创建一个工厂类来支持如下所示的viewmodel,

class SampleFactory @Inject constructor(var dataManager:DataManager): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
    if (modelClass.isAssignableFrom(SampleViewModel::class)) {
        return SampleViewModel(dataManager) as T
    }
    throw IllegalStateException()
}

}

现在在您的模块类中,您可以按以下方式注入上述类,(Note-Datamanager类是可注入的)

//Provide Factory
@Provides
fun provideFactory(dataManager:DataManager): SampleFactory {
    return SampleFactory(dataManager)
}

//Provide actual viewmodel
@Provides
fun provideViewModel(sampleFactory: SampleFactory): SampleViewModel {
    return ViewModelProviders.of(fragment, sampleFactory)[SampleViewModel::class]
}

否,在您的Fragment中,您可以像其他依赖项一样注入视图模型,

@Injetct
lateinit viewModel:SampleViewModel

答案 1 :(得分:0)

您可以使用 Koin 作为Dagger的替代方法。 Koin完全支持Android体系结构ViewModel 。它非常易于使用。我更喜欢中小型项目。

// declared ViewModel using the viewModel keyword
val myModule : Module = module {
    viewModel { MyViewModel(get()) } 
    ...
}

// Just get it
class MyActivity() : AppCompatActivity() {

    // lazy inject MyViewModel
    val myViewModel : MyViewModel by viewModel()
}

insert-koin.io