首页 > 解决方案 > 在 BaseViewModel 中注入依赖项

问题描述

我有一个项目,其中基本逻辑应用于应用程序中的所有屏幕。所以我把这个逻辑移到了 BaseViewModel。在其中我需要存储库和路由器等依赖项。我不能将这些依赖项作为构造函数参数提供,因为我需要继承这个类。所以我只使用场注入。

BaseViewModelImpl.kt

abstract class BaseViewModelImpl : ViewModel(), BaseViewModel {
    override val singleLiveData = MutableLiveData<LiveDataEvent<String>>()
    override var isViewDestroyed: Boolean = true

    protected val compositeDisposable = CompositeDisposable()

    private val repo by inject<Repo>()
    private val router by inject<Router>()

    init {
        KTP.openRootScope().inject(this) //Warning: Leaking 'this' in constructor of non-final class BaseViewModelImpl

        subscribeToCommonWork()
    }


    private fun subscribeToCommonWork() {
        repo.publishRelay
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                if (!isViewDestroyed)
                    handleEvent(it)
            }, { }).addTo(compositeDisposable)
    }

    open fun handleEvent(event: String) {
        singleLiveData.value = LiveDataEvent(event)
    }

    override fun onCleared() {
        super.onCleared()
        compositeDisposable.dispose()
    }

    override fun onForwardClick() {
        router.moveForward()
    }
}

BaseFragment.kt

abstract class BaseFragment<VM : BaseViewModel> : Fragment(), DialogListener {
    abstract val viewModel: VM

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewModel.isViewDestroyed = false

        viewModel.singleLiveData.observe(viewLifecycleOwner) { event ->
            event.getContentIfNotHandled()?.let {
                Dialog.newInstance(it).show(childFragmentManager, Dialog::class.simpleName)
            }
        }
    }

    override fun onForwardClick() {
        viewModel.onForwardClick()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        viewModel.isViewDestroyed = true
    }
}

这是一个好方法吗?有没有办法避免有关泄漏的警告?哪个范围更适合用于 BaseViewModel?

PS var isViewDestroyed 用于不在前一个片段上显示对话框(当我们向前移动时)。

您可以在这里看到完整的项目: https ://github.com/FirstSpectr/ViewModelInheritance

标签: androidandroid-mvvmtoothpick-di

解决方案


推荐阅读