Kir*_*man 10 android dependency-injection kotlin android-architecture-components
我正在将我的应用程序转换为使用ViewModels。为了实例化ViewModels 我使用自定义Factory和 Dagger 2 进行依赖注入。它看起来像这样:
@Singleton
class ViewModelFactory @Inject constructor(
private val viewModels: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T
= viewModels[modelClass]!!.get() as T
}
@Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) @MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
@Module
abstract class ViewModelModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds @IntoMap @ViewModelKey(FooViewModel::class)
abstract fun fooViewModel(viewModel: FooViewModel): ViewModel
}
Run Code Online (Sandbox Code Playgroud)
现在我面临的问题,如何访问参数/附加Bundle我的Fragment还是Activity内部的ViewModel。这是必要的,因为视图以及 中的数据ViewModel通常是可参数化的。我将如何使用最少的样板来实现这一点?
如果您使用Saved State模块,则活动意图附加和片段参数都可以通过SavedStateHandle获得
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() {
init {
val someArgument = state.get<String>("someArgumentKey")
...
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用AssistedInject库将参数从 Activity/Fragment 传递到 ViewModel,但它是一个样板解决方案。这是一个匕首示例,另一个使用匕首柄的示例。
将这些额外的参数/参数注入到你的视图模型中怎么样?您可以通过使用 dagger 访问此类活动/片段来实现此目的。
@Module
class IntentModule {
@Provides
fun retriveIntentWithExtraX(activity: DestinationActivity): Long {
return activity.intent.getSerializableExtra(SOME_EXTRA_DATA) as Long
}
}
Run Code Online (Sandbox Code Playgroud)
并在模块内部包含您的活动/片段:
@Module
abstract class ActivityModules {
@ContributesAndroidInjector(modules = [IntentModule::class])
abstract fun contributeDestinationActivity(): DestinationActivity
}
Run Code Online (Sandbox Code Playgroud)
最后你可以将这样的参数/额外注入到你的 ViewModel 中,如下所示:
class SomeViewModel @Inject constructor(
private val someExtraData: Long
) : ViewModel()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2098 次 |
| 最近记录: |