如何将 ViewModel AssistedFactory 绑定到 Activity
How to bind N ViewModelAssistedFactory to Activity
这是我实现 Lifecycle SavedState 逻辑的 DI 设置:
BaseActivityModule:
@Module
abstract class BaseActivityModule<A : AppCompatActivity> {
@Binds
abstract fun provideActivity(activity : A): AppCompatActivity
@Binds
internal abstract fun bindSavedStateRegistryOwner(activity : A): SavedStateRegistryOwner
@Module
companion object {
@Provides
@ActivityContext
fun provideContext(activity: AppCompatActivity): Context = activity
}
}
SplashActivityModule:
@Module
abstract class SplashActivityModule : BaseActivityModule<SplashActivity>() {
@Binds
@IntoMap
@ViewModelKey(SplashViewModel::class)
abstract fun bindFactory(factory: SplashViewModel.Factory): ViewModelAssistedFactory<out ViewModel>
@Module
companion object{
@JvmStatic
@Nullable
@Provides
fun provideDefaultArgs(): Bundle? {
return null
}
}
}
ViewModel:
class SplashViewModel @AssistedInject constructor(
@Assisted stateHandle: SavedStateHandle,
...
) : BaseViewModel(stateHandle,...) {
@AssistedInject.Factory
interface Factory : ViewModelAssistedFactory<SplashViewModel>
}
现在假设我想添加另一个 ViewModel
到我的 Activity
,这将失败:
另一个视图模型:
class AnotherViewModel @AssistedInject constructor(
@Assisted stateHandle: SavedStateHandle,
...
) : BaseViewModel(stateHandle,...) {
@AssistedInject.Factory
interface Factory : ViewModelAssistedFactory<AnotherViewModel>
}
SplashActivityModule:
@Module
abstract class SplashActivityModule : BaseActivityModule<SplashActivity>() {
@Binds
@IntoMap
@ViewModelKey(SplashViewModel::class)
abstract fun bindFactory(factory: SplashViewModel.Factory): ViewModelAssistedFactory<out ViewModel>
@Binds
@IntoMap
@ViewModelKey(AnotherViewModel::class)
abstract fun bindAnotherFactory(factory: AnotherViewModel.Factory): ViewModelAssistedFactory<out ViewModel>
@Module
companion object{
@JvmStatic
@Nullable
@Provides
fun provideDefaultArgs(): Bundle? {
return null
}
}
}
error: [Dagger/MissingBinding]
....AnotherViewModel cannot be
provided without an @Inject constructor or an @Provides-annotated
method. public abstract interface ApplicationComponent extends
dagger.android.AndroidInjector<...Application> {
我怎样才能使这个工作?
好的,我发现了,只少了一块拼图。
我只创建了由 ChildActivity 的参数接收的 ViewModel。为了能够使用 N 个 ViewModel,ChildActivity 负责像 BaseActivity 一样提供它们。所以,我只需要在 SplashActivity 中添加我的 ViewModel
实例化:
class SplashActivity : BaseActivity<ActivitySplashBinding, SplashViewModel>() {
private val anotherViewModel by lazy { ViewModelProvider(this, viewModelFactory).get(AnotherViewModel::class.java) }
...
binding.anotherViewModel = anotherViewModel
}
现在可以使用了!
这是我实现 Lifecycle SavedState 逻辑的 DI 设置:
BaseActivityModule:
@Module
abstract class BaseActivityModule<A : AppCompatActivity> {
@Binds
abstract fun provideActivity(activity : A): AppCompatActivity
@Binds
internal abstract fun bindSavedStateRegistryOwner(activity : A): SavedStateRegistryOwner
@Module
companion object {
@Provides
@ActivityContext
fun provideContext(activity: AppCompatActivity): Context = activity
}
}
SplashActivityModule:
@Module
abstract class SplashActivityModule : BaseActivityModule<SplashActivity>() {
@Binds
@IntoMap
@ViewModelKey(SplashViewModel::class)
abstract fun bindFactory(factory: SplashViewModel.Factory): ViewModelAssistedFactory<out ViewModel>
@Module
companion object{
@JvmStatic
@Nullable
@Provides
fun provideDefaultArgs(): Bundle? {
return null
}
}
}
ViewModel:
class SplashViewModel @AssistedInject constructor(
@Assisted stateHandle: SavedStateHandle,
...
) : BaseViewModel(stateHandle,...) {
@AssistedInject.Factory
interface Factory : ViewModelAssistedFactory<SplashViewModel>
}
现在假设我想添加另一个 ViewModel
到我的 Activity
,这将失败:
另一个视图模型:
class AnotherViewModel @AssistedInject constructor(
@Assisted stateHandle: SavedStateHandle,
...
) : BaseViewModel(stateHandle,...) {
@AssistedInject.Factory
interface Factory : ViewModelAssistedFactory<AnotherViewModel>
}
SplashActivityModule:
@Module
abstract class SplashActivityModule : BaseActivityModule<SplashActivity>() {
@Binds
@IntoMap
@ViewModelKey(SplashViewModel::class)
abstract fun bindFactory(factory: SplashViewModel.Factory): ViewModelAssistedFactory<out ViewModel>
@Binds
@IntoMap
@ViewModelKey(AnotherViewModel::class)
abstract fun bindAnotherFactory(factory: AnotherViewModel.Factory): ViewModelAssistedFactory<out ViewModel>
@Module
companion object{
@JvmStatic
@Nullable
@Provides
fun provideDefaultArgs(): Bundle? {
return null
}
}
}
error: [Dagger/MissingBinding] ....AnotherViewModel cannot be provided without an @Inject constructor or an @Provides-annotated method. public abstract interface ApplicationComponent extends dagger.android.AndroidInjector<...Application> {
我怎样才能使这个工作?
好的,我发现了,只少了一块拼图。
我只创建了由 ChildActivity 的参数接收的 ViewModel。为了能够使用 N 个 ViewModel,ChildActivity 负责像 BaseActivity 一样提供它们。所以,我只需要在 SplashActivity 中添加我的 ViewModel
实例化:
class SplashActivity : BaseActivity<ActivitySplashBinding, SplashViewModel>() {
private val anotherViewModel by lazy { ViewModelProvider(this, viewModelFactory).get(AnotherViewModel::class.java) }
...
binding.anotherViewModel = anotherViewModel
}
现在可以使用了!