如何将 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    
}

现在可以使用了!