【问题标题】:how to create new instance of viewModel in koin every time每次如何在koin中创建viewModel的新实例
【发布时间】:2023-03-19 14:32:01
【问题描述】:

我在我的项目中使用 Koin 作为 依赖注入模式,每当我加载片段/活动时,我都需要创建新实例,现在使用以下模式,任何解决方案为此,它可能会节省大量时间。

private val homeViewModel: HomeViewModel by viewModel()

【问题讨论】:

  • 如果你有这个类,你可以在 BaseActivity 或 BaseFragment 中完成
  • 我都有,我怎么能从那里点呢?

标签: android mvvm viewmodel koin


【解决方案1】:

将 ViewModel 定义为 BaseFragment 类中的抽象,并在扩展 BaseFragment 时设置值。

abstract class BaseFragment<Binding : ViewDataBinding, ViewModel : BaseViewModel> : Fragment(){
            protected var bindingObject: Binding? = null
            protected abstract val mViewModel: ViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            bindingObject = DataBindingUtil.inflate(inflater, getLayoutResId(), container, false)
            return bindingObject?.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        performDataBinding()
    }

    @LayoutRes
    abstract fun getLayoutResId(): Int

    private fun performDataBinding() {
        bindingObject?.setLifecycleOwner(this)
        bindingObject?.setVariable(BR.viewModel, mViewModel)
        bindingObject?.executePendingBindings()
    }

}

在你的片段中

    class FragmentNew : BaseFragment<FragmentNewBinding, FragmentNewVM>() {
       // Here is the your viewmodel imlementation. Thus when you create fragment it's by default override method
       override val mViewModel: FragmentNewVM by viewModel() 

       override fun getLayoutResId(): Int = [fragment layout id like "R.layout.fragment_new"]
   }

【讨论】:

    【解决方案2】:

    问题是为什么每次都需要新实例? ViewModel 的整个概念是保留相同的实例和数据。 viewModel {} 每次注入时都会创建新实例,除非它未共享。

    不知道为什么它不适合你,但我认为你可以使用 factory{} 而不是 viewModel{}

    factory{
        // this is because you need new instance everytime.
        HomeViewModel()
    }
    

    【讨论】:

    • Koin 中没有 api 用于: private val homeViewModel: HomeViewModel by factory { HomeViewModel() } 有人会希望新实例清除实时数据缓存。
    【解决方案3】:

    您将希望放弃使用by viewmodel 并直接实例化该类。可以通过getKoin().get()获取全局(作用域)变量。

    private val viewModel = HomeViewModel(getKoin().get())
    

    【讨论】:

      猜你喜欢
      • 2018-09-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多