模块中共享 ViewModel

问题描述 投票:0回答:1

我有一个 Activity,下面有多个片段。我想与共享视图模型共享数据,但它们都位于不同的模块中。我无法获取 ActivityViewModel 类。当我使用 ActivityViewModel 的父级 CoreViewModel 接收到 ActivityViewModels() 时,我得到的对象与使用 ActivityViewModel 接收到的对象不同,如何在多个模块中共享 ViewModel

这是我将它们移动到同一个模块后打印的日志,但这不是我想要的方式

在主活动中

 extend ->MainViewModel:CoreViewModel:ViewModel
 val mV0 by viewModels<MainViewModel>()
 LogD("mViewModel0 = $mV0")

在 MineFragment 中(该 Fragment 是 MainActivity 子级,为了获取 MainViewModel.class,我将 MineFragment 移至与 MainActivity 相同的模块)

 val mV1 by activityViewModels<MainViewModel>()
 val mV2 by activityViewModels<CoreViewModel>()
 LogD("mViewModel1 = $mV1")
 LogD("mViewModel2 = $mV2")

记录信息

mViewModel0 = com.nf.bitcoinexchange.activities.main.MainViewModel@6505362
mViewModel1 = by activityViewModels<MainViewModel>()= com.nf.bitcoinexchange.activities.main.MainViewModel@6505362
mViewModel2 = by activityViewModels<CoreViewModel>()= com.nf.corelib.viewmodel.CoreViewModel@3290057

我用的翻译软件可能有点不清楚...抱歉

android kotlin mvvm viewmodel android-viewmodel
1个回答
0
投票

O找到了两种方法来做到这一点

#1 - 将 viewModel 的字段存储在伴随对象中。

这样所有实例都将访问相同的数据 优点

  • viewModel 可以通过通常的方式创建,“通过activityViewModels()” 或“通过 viewModels()”:

private val sharedViewModel: SharedViewModel by viewModels()
or
private val sharedViewModel: SharedViewModel by activityViewModels()

缺点

  • 将创建 viewModel 的两个(或更多)实例

#2 - 创建您自己的“ViewModelFactory” 这样您就可以控制它的创建,并作为单个实例提供 优点

  • 只会创建一个 viewModel 实例

缺点

  • 无法使用SavedStateHandle
  • 获取viewModel实例的方式稍微费力一点:

lateinit var sharedViewModelFactory :  SharedViewModelFactory
private lateinit var sharedViewModel: SharedViewModel
...
sharedViewModel = ViewModelProvider(this,sharedViewModelFactory).get(SharedViewModel::class.java)

创建工厂的代码如下:

package ...login.data.dependencyInjection

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
...
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityScoped
import dagger.hilt.components.SingletonComponent
import javax.inject.Inject
import javax.inject.Scope
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
class SharedViewModelModule {

    @Singleton
    @Provides
    fun provideViewModelInstanceHolder(): ViewModelInstanceHolder {
        return ViewModelInstanceHolder()
    }

    @Singleton
    @Provides
    fun provideUserViewModelFactory(
        viewModelInstanceHolder: ViewModelInstanceHolder
    ): SharedViewModelFactory {
        return SharedViewModelFactory(
            viewModelInstanceHolder
        )
    }
}

class ViewModelInstanceHolder() {
    companion object {
        var sharedViewModel: SharedViewModel? = null
    }

    fun getInstance(): SharedViewModel {
        if (sharedViewModel == null) {
            sharedViewModel = SharedViewModel()
        }
        return sharedViewModel!!
    }
}

class SharedViewModelFactory @Inject constructor(private val viewModelInstanceHolder: ViewModelInstanceHolder) :
    ViewModelProvider.NewInstanceFactory() {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return viewModelInstanceHolder.getInstance() as T
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.