我有一个 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
我用的翻译软件可能有点不清楚...抱歉
O找到了两种方法来做到这一点
#1 - 将 viewModel 的字段存储在伴随对象中。
这样所有实例都将访问相同的数据 优点
private val sharedViewModel: SharedViewModel by viewModels()
or
private val sharedViewModel: SharedViewModel by activityViewModels()
缺点
#2 - 创建您自己的“ViewModelFactory” 这样您就可以控制它的创建,并作为单个实例提供 优点
缺点
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
}
}