我在我的应用程序中使用Dagger2最新的Android注入模型(带AndroidInjection
类)。到目前为止,一切都运行良好,包括ViewModelFactory
注入,但我的ViewModel上只有无参数构造函数。
在实现新功能时,我创建了一个扩展AndroidViewModel
的ViewModel(我需要该视图模型中的上下文)。 AndroidViewModel
需要Application
作为构造函数参数,因此我将其作为注入参数添加到我的ViewModel的构造函数中。
从那时起,Dagger2无法编译并出现以下错误:
AppComponent.java:6:错误:[dagger.android.AndroidInjector.inject(T)] 没有@Inject就无法提供android.app.Application 构造函数或来自@ Provide-annotated方法。
我理解这意味着我的Application
对象在图表中不可用,但我将其添加到我的App类中,因此我真的不知道如何纠正它。
以下是我的流程中涉及的类。我将标记为我的上一个功能所做的任何更改:
class MobileApp : DaggerApplication() {
override fun applicationInjector() = DaggerAppComponent.builder()
.application(this)
.build()
override fun onCreate() {
super.onCreate()
AppInjectorKt.injectApp(this)
}
}
AppComponent.kt:
@Singleton
@Component(modules = arrayOf(
AndroidSupportInjectionModule::class,
AppModule::class,
ActivityBuilder::class))
interface AppComponent : AndroidInjector<MobileApp> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: MobileApp): Builder
fun build(): AppComponent
}
override fun inject(app: MobileApp)
}
AppModule.kt:
@Module(includes = arrayOf(ViewModelModule::class))
class AppModule
ActivityBuilder.kt:
@Module
internal abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = arrayOf(ResultModule::class))
internal abstract fun contributeResultActivity(): ResultActivity
//This block is new
@ContributesAndroidInjector(modules = arrayOf(AltimeterActivityModule::class))
internal abstract fun contributeAltimeterActivity(): AltimeterActivity
}
ViewModelModule.kt:
@Module
internal abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(ResultViewModel::class)
abstract fun bindResultViewModel(resultViewModel: ResultViewModel): ViewModel
//This block is new
@Binds
@IntoMap
@ViewModelKey(AltimeterActivityViewModel::class)
abstract fun bindAltimeterActivityViewModel(altimeterActivityViewModel: AltimeterActivityViewModel): ViewModel
@Binds
abstract fun bindViewModelFactory(factory: JumpTrackerViewModelFactory): ViewModelProvider.Factory
}
JumpTrackerViewModelFactory.kt:
@Singleton
class JumpTrackerViewModelFactory @Inject
constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>)
: ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
var creator: Provider<ViewModel>? = creators[modelClass]
if (creator == null) {
for ((key, value) in creators) {
if (modelClass.isAssignableFrom(key)) {
creator = value
break
}
}
}
if (creator == null) throw IllegalArgumentException("unknown model class " + modelClass)
try {
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
ResultActivity.kt:
class ResultActivity : AppCompatActivity(), Injectable {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var viewModel: ResultViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
[...]
viewModel = ViewModelProviders.of(this, viewModelFactory)[ResultViewModel::class.java]
[...]
ResultViewModel.kt:
class ResultViewModel @Inject constructor() : ViewModel() {
[...]
AltimeterActivity.kt(这个类是新的):
class AltimeterActivity : AppCompatActivity(), Injectable {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var viewModel: AltimeterActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this, viewModelFactory)[AltimeterActivityViewModel::class.java]
[...]
AltimeterActivityViewModel.kt(此类是新的):
class AltimeterActivityViewModel @Inject constructor(app : Application) : AndroidViewModel(app) {
companion object {
val TAG = "AltimeterViewModel"
}
var pressureAltitudeLiveData = PressureAltitudeLiveData(app)
}
此外,我已经修改了我的代码以尝试App注入,并且它正在工作,所以我知道应用程序有效地正确注入:
AppModule.kt:
@Module(includes = arrayOf(ViewModelModule::class))
class AppModule {
@Singleton @Provides
fun provideThing(app : Application) : String {
return "dqwdwqd"
}
}
AltimeterActivityViewModel.kt:
class AltimeterActivityViewModel @Inject constructor(/*app : Application*/) : /*Android*/ViewModel(/*app*/) {
companion object {
val TAG = "AltimeterViewModel"
}
// var pressureAltitudeLiveData = PressureAltitudeLiveData(app)
}
如果有人对发生的事情有任何线索,感谢您分享您的想法!