gpt4 book ai didi

android - 使用 kodein 在 ViewModelFactory 中注入(inject)保存的状态

转载 作者:行者123 更新时间:2023-12-02 13:18:45 27 4
gpt4 key购买 nike

我用 MVVM 模式开发应用程序。我想在用户旋转屏幕时保存 UI。

MyViewModel.kt

class MyViewModel(val repository: SomeRepository,
state : SavedStateHandle) : ViewModel() {

private val savedStateHandle = state
companion object {
const val KEY = "KEY"
}

fun saveCityId(cityId: String) {
savedStateHandle.set(CITY_KEY, cityId)
}

fun getCityId(): String? {
return savedStateHandle.get(CITY_KEY)
}

}

ViewModelFactory.kt
@Suppress("UNCHECKED_CAST")
class ViewModelFactory(
private val repository: SomeRepository,
private val state: SavedStateHandle
) : ViewModelProvider.NewInstanceFactory() {

override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MyViewModel(repository,state) as T
}

}

我在 MainActivity 中调用它
MainActivity.kt
class MainActivity: AppCompatActivity(), KodeinAware {
private val factory: ViewModelFactoryby instance()
override val kodein by kodein()
private lateinit var viewModel: MyViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
cityId = intent.getStringExtra("cityId") ?: viewModel.getCityId()
if (cityId != null) {
viewModel.saveCityId(cityId!!)
viewModel.getCurrentWeather(cityId!!)
}
}

在这里我注入(inject)依赖项

申请.kt
class ForecastApplication: Application(), KodeinAware {
override val kodein = Kodein.lazy {
import(androidXModule(this@ForecastApplication))

bind<SomeApi>() with singleton {
Retrofit.create()
}

bind<WeatherRepository>() with singleton {
WeatherRepository(instance())
}
bind() from provider {
WeatherViewModelFactory(
instance(), instance()
)
}
}
}

我有这个错误
 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.simpleforecast/com.example.simpleapp.UI.Cities.Activity}:org.kodein.di.Kodein$NotFoundException: No binding found for bind<SavedStateHandle>() 
with ?<Activity>().? { ? }


我应该如何构建 ViewModelFactory 并为 ViewModel 注入(inject) Saved State 模块?

最佳答案

SavedStateHandle是不能绑定(bind)到 DI 图的参数,因为它是从 Fragment 检索的(或 Activity ),因此您需要执行几个步骤才能使其工作:

1) DI viewmodel 定义 - 因为你有自定义参数,你需要使用 from factory :

bind() from factory { handle: SavedStateHandle ->
WeatherViewModel(
state = handle,
repository = instance()
)
}

2) ViewModel Factory - 您需要从 AbstractSavedStateViewModelFactory 继承

val vmFactory = object : AbstractSavedStateViewModelFactory(this, arguments) {
override fun <T : ViewModel> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {
val vmFactory: ((SavedStateHandle) -> WeatherViewModel) = kodein.direct.factory()
return vmFactory(handle) as T
}
}
create的内部从 DI 图中检索工厂的方法(从步骤 1 开始)。

3)您使用指定的工厂检索 ViewModel:
lateinit var vm : WeatherViewModel

fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
vm = ViewModelProvider(this, vmFactory)[WeatherViewModel::class.java]
}

或安卓 KTX 方式:
val vm : WeatherViewModel by viewModels { vmFactory }

关于android - 使用 kodein 在 ViewModelFactory 中注入(inject)保存的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60762599/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com