当前位置: 首页 > 知识库问答 >
问题:

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

澹台锐
2023-03-14

我正试图在计算机上实现这个例子https://developer.android.com/jetpack/docs/guide.这就解释了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个答案

訾安邦
2023-03-14

你可以用Koin作为匕首的替代品。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()
}

插入koin。木卫一

令狐宏伟
2023-03-14

如果你想在你的片段中提供构造函数作为依赖的视图模型,有一个不同的方法,

假设你有一个视图模型类,如下所示,

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

然后需要创建一个factory类来支持上面的viewmodel,如下所示,

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

}

现在在你的模块类中,你可以像下面一样注入上面的类,(注意-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]
}

不,在你的片段中,你可以像其他依赖一样注入你的viewmodel,

@Injetct
lateinit viewModel:SampleViewModel
 类似资料:
  • 好的,到目前为止还好。但是等等,突然A需要额外的输入,比如一个对它的构造至关重要的名为“amount”的整数。现在,我的A构造函数需要如下所示: 突然这个新参数干扰了注射。此外,即使这确实有效,我也无法在从提供者检索新实例时输入“金额”,除非我弄错了。这里有几件事我可以做,我的问题是哪一件是最好的? 我可以通过添加一个方法来重构A,该方法应该在构造函数之后调用。然而,这是很难看的,因为它迫使我推迟

  • 和另一个类: 在这种情况下,服务将按照预期注入到A类中。据我所知,你不能在a类中使用构造函数,否则注入将无法工作。有没有一种方法可以在a类中使用一个构造函数,同时注入服务?即: 在这种情况下,我得到的服务是空的,无论如何要解决这个问题?我希望能够从类型A中使用“new”创建一个对象,并注入服务,这可能吗?

  • 我正在使用spring官方教程中的示例进行实验,并且对此代码有一个依赖关系: https://github.com/spring-guides/gs-async-method/tree/master/complete 如果您查看类上的代码,我有两个问题: 当服务器启动时,如果我在这个类的构造函数中放置一个断点,就像在构造函数中一样,是由spring使用配置的bean提供的。但是,构造函数上没有注释

  • 我需要重构现有的抽象类来实现依赖注入,但是这个类有两个接受其他参数的构造函数。 我需要注入一些接口,并避免在构造函数中传递任何其他参数,如“settingsId”和“Setting”。所以我的想法是在创建此类的实例后创建两种方法来设置这些参数。 但它看起来不是一个合适的解决方案,因为如果开发人员忘记在创建实例后运行这些方法之一,我们将来可能会得到一个异常(对象未设置为引用...)。我应该如何正确执

  • 在之前的所有JUnit版本中,测试构造函数或方法都不允许有参数(至少不能使用标准的Runner实现)。作为JUnit Jupiter的主要变化之一,测试构造函数和方法现在都允许有参数。这带来了更大的灵活性,并为构造函数和方法启用依赖注入。 ParameterResolver定义了测试扩展的API,希望在运行时动态解析参数。如果测试构造函数或@Test, @TestFactory, @BeforeE

  • 问题内容: 我发现我的构造函数开始看起来像这样: 不断增加的参数列表。由于“容器”是我的依赖项注入容器,所以为什么我不能这样做: 每堂课?不利之处是什么?如果执行此操作,则感觉就像我在使用精美的静态方法。请分享你对IoC和依赖注入疯狂的想法。 问题答案: 正确的是,如果将容器用作服务定位器,则它或多或少是光荣的静态工厂。由于种种原因,我认为这是一种反模式。 构造函数注入的奇妙好处之一是,它使违反单