使用dagger2在多个片段中使用视图模型的相同实例

我在我的项目中仅使用dagger2(而不是dagger-android)。使用multibinding注入ViewModel很好。但是以前没有dagger2的地方存在一个问题,我在多个片段中使用了活动中使用的相同viewmodel实例(使用fragment-ktx方法activityViewModels()),但是现在由于dagger2注入了视图模型,因此它总是提供新实例(检查每个片段的viewmodel的每个片段中的hashCode),这只是中断了使用viewmodel的片段之间的通信。

片段和视图模型代码如下:

class MyFragment: Fragment() {
    @Inject lateinit var chartViewModel: ChartViewModel

    override fun onAttach(context: Context) {
        super.onAttach(context)
        (activity?.application as MyApp).appComponent.inject(this)
    }

}

//-----ChartViewModel class-----

class ChartViewModel @Inject constructor(private val repository: ChartRepository) : BaseViewModel() {
   //live data code...
}

这是视图模型依赖注入的代码:

//-----ViewModelKey class-----

@MapKey
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)

//-----ViewModelFactory class------

@Singleton
@Suppress("UNCHECKED_CAST")
class ViewModelFactory
@Inject constructor(
    private val viewModelMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        val creator = viewModelMap[modelClass] ?: viewModelMap.asIterable()
            .firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
        ?: throw IllegalArgumentException("Unknown ViewModel class $modelClass")

        return try {
            creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
    }
}

//-----ViewModelModule class-----

@Module
abstract class ViewModelModule {
    @Binds
    internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory

    @Binds
    @IntoMap
    @ViewModelKey(ChartViewModel::class)
    abstract fun bindChartViewModel(chartViewModel: ChartViewModel): ViewModel
}

有什么方法可以为多个片段实现相同的视图模型实例,也可以同时将视图模型注入片段中。 另外,也需要bindViewModelFactory方法,因为即使没有此方法,它似乎也对应用程序没有影响。

一种解决方法是为共享通用视图模型的片段制作BaseFragment,但这又包括样板代码,而且我也不是BaseFragment / BaseActivity的忠实拥护者。

这是为ChartViewModel生成的代码,该代码始终创建viewModel的newInstance:

@SuppressWarnings({
    "unchecked",
    "rawtypes"
})
public final class ChartViewModel_Factory implements Factory<ChartViewModel> {
  private final Provider<ChartRepository> repositoryProvider;

  public ChartViewModel_Factory(Provider<ChartRepository> repositoryProvider) {
    this.repositoryProvider = repositoryProvider;
  }

  @Override
  public ChartViewModel get() {
    return newInstance(repositoryProvider.get());
  }

  public static ChartViewModel_Factory create(Provider<ChartRepository> repositoryProvider) {
    return new ChartViewModel_Factory(repositoryProvider);
  }

  public static ChartViewModel newInstance(ChartRepository repository) {
    return new ChartViewModel(repository);
  }
}