我正在使用Dagger-Hilt在我的Android项目中进行依赖注入,现在我遇到了这样的情况,我有一个基本的抽象片段
abstract class BaseViewModel constructor(
val api: FakeApi,
) : ViewModel() {
//...
}
在这里,我有一个依赖项,即FakeApi
。我正在尝试做的是将FakeApi
注入到BaseViewModel中,以便在BaseViewModel
及其所有子项中可用。
@HiltViewModel
class TaskViewModel @Inject constructor(
api: FakeApi
) : BaseViewModel(api){
}
这种方法工作得很好,但是我不需要将依赖关系从子
传递到超级
类,我需要将FakeApi
自动注入BaseViewModel
中而不必传递它,因为我有三个抽象级别(还有一个类继承自TaskViewModel)所以我必须传递两次。
abstract class BaseViewModel: ViewModel() {
@Inject
lateinit var api: FakeApi
//...
}
@HiltViewModel
class TaskViewModel @Inject constructor(): BaseViewModel() {
}
这种方法对我不起作用,没有注入< code>FakeApi,我得到了一个< code >异常
kotlin.UninitializedPropertyAccessException: lateinit property api has not been initialized
超级
类使用构造函数注入,而不是从子
传递依赖项?我测试了一下,我看到基类
中的场注入仍然适用于 Hilt 2.35。我不能像你一样得到错误,所以也许你可以尝试更改希尔特版本或检查你如何提供FakeApi
abstract class BaseViewModel : ViewModel() {
@Inject
protected lateinit var fakeApi: FakeApi
}
FakeApi
// Inject constructor also working
class FakeApi {
fun doSomeThing() {
Log.i("TAG", "do something")
}
}
主视图模型
@HiltViewModel
class MainViewModel @Inject constructor() : BaseViewModel() {
// from activity, when I call this function, the logcat print normally
fun doSomeThing() {
fakeApi.doSomeThing()
}
}
应用模块
@Module
@InstallIn(SingletonComponent::class)
class AppModule {
@Provides
fun provideAPI(
): FakeApi {
return FakeApi()
}
}
https://github.com/PhanVanLinh/AndroidHiltInjectInBaseClass
多亏了这个 Github 问题,我发现问题是你不能在 ViewModel 构造函数初始化期间使用字段注入的属性,但在构造函数(包括所有属性直接初始化)初始化后仍然使用它。
Dagger首先完成构造器注入过程,然后进行现场注入过程。这就是为什么在构造函数注入完成之前不能使用字段注入的原因。
abstract class BaseViewModel : ViewModel() {
@Inject
protected lateinit var fakeApi: FakeApi
val temp = fakeApi.doSomething() // Don't use it in direct property declaration
init {
fakeApi.doSomething() // Don't use it in the init block
}
}
kotlin prettyprint-override">abstract class BaseViewModel : ViewModel() {
@Inject
protected lateinit var fakeApi: FakeApi
val temp: Any
get() = fakeApi.doSomething() // Use property getter
fun doSomething(){
fakeApi.doSomething() // Use it after constructor initialization
}
}
或者,您可以使用lazy</code>的<code>来声明属性。
我试图使用hilt将viewmodel注入片段,为此我创建了两个模块,一个用于我的网络组件,另一个用于角色的viewmodel。 网络模块安装在单例组件中,我需要将字符模块安装在FragmentComponent中,以通过“by view模型()”获取视图模型 我的活动和片段用“@AndroidEntryPoint”注释,我的应用程序用“@HiltAndroidApp”注释。我的模块是: 我的视图
我正在使用更新动作栏中的标题 共享视图模型 主要活动观察者 使用下面的代码似乎会在< code>Fragment中创建新的实例(在调试器中检查): 但似乎是这样的 文章参考 这是应该这样做还是我做错了什么? 谢谢你!
在过去,Google提供了碎片类(这里我也问过我们什么时候应该使用它)。 现在,Android 4.4有了一个新的框架类,叫做“场景”。 根据我所读到的(和在课堂上看的,例如这里),它应该帮助你在状态之间的动画和转换。 这个有官方的样品吗? 是否有兼容库,可以在4.4之前的版本上使用它?
如何注入抽象类我有一个抽象类 我尝试使用< code>@Module和< code>@Binds注释来初始化该类的对象。但这并不能创建并抛出一个错误。 但这给出了错误。我犯了什么错误?请您告诉我如何为抽象类创建。我们如何注入抽象类?从文档中,它说。有时,不能注入构造函数。发生这种情况可能有多种原因。例如,不能构造函数注入接口。也不能构造函数注入不属于的类型,例如外部库中的类。在这些情况下,您可以使
我正在写一个使用片段的简单示例。在主体活动中,有两个片段。第一个片段有一些文本视图,第二个片段有一些按钮。当用户点击textview时,文本打开按钮将被更改。 activity_main.xml mainactivity.java contentFrag.java 我没有编写控制按钮的操作,只是生成onclick事件。但是,我弄错了。请帮助我修复错误,并继续完成我的任务。
我有一个ViewPagerContainer片段,在应用程序启动时加载。ViewPagerContainer片段将两个选项卡(选项卡A和选项卡B)添加到操作栏。选项卡B有两个项目的列表视图。 我所做的:我在选项卡B片段中的列表视图项上附加了一个click listener,这样当用户单击一个项时,它会在第一个片段(即选项卡B下)内打开另一个片段(子片段)。 我陷入困境的地方:当用户按下后退按钮时,