我在Kotlin中使用Koin库进行DIKoin提供by viewmodel(),用于获取ViewModel by sharedViewModel()的示例,以获取片段中的相同示例。如何在活动中获得相同的ViewModel示例?我没有找到任何方法来实现这一点。
Koin
by viewmodel()
by sharedViewModel()
bz4sfanl1#
你需要阅读更多关于ViewModel的内容来更好地理解它。https://developer.android.com/topic/libraries/architecture/viewmodelViewModel已连接到您的Activity因此您只能在他Fragments之间共享您的ActivityViewModel,这就是koin中sharedViewModel含义如果将ViewModel Factory与相同的context一起使用,则sharedViewModel相同。在Activities之间共享任何数据都可以通过Intent来完成,在Android中没有其他方法,或者您可以保留一些static / global数据,并在Activities之间共享
ViewModel
Activity
Fragments
koin
sharedViewModel
ViewModel Factory
context
Activities
Intent
static / global
g6baxovj2#
我建议将应用程序设置为ViewModelStoreOwner,并注入viewModel,将其作为应用程序的所有者。
ViewModelStoreOwner
class App : Application(), ViewModelStoreOwner { private val mViewModelStore = ViewModelStore() override fun getViewModelStore(): ViewModelStore { return mViewModelStore } }
您可以定义一些扩展来轻松地注入viewModel
val Context.app: App get() = applicationContext as App inline fun <reified T : ViewModel> Context.appViewModel( qualifier: Qualifier? = null, noinline state: BundleDefinition? = null, noinline parameters: ParametersDefinition? = null ): Lazy<T> { return lazy(LazyThreadSafetyMode.NONE) { GlobalContext.get().getViewModel(qualifier, state, { ViewModelOwner.from(app, null) }, T::class, parameters) } } inline fun <reified T : ViewModel> Fragment.appViewModel( qualifier: Qualifier? = null, noinline state: BundleDefinition? = null, noinline parameters: ParametersDefinition? = null ): Lazy<T> { return lazy(LazyThreadSafetyMode.NONE) { GlobalContext.get().getViewModel(qualifier, state, { ViewModelOwner.from(requireContext().app, null) }, T::class, parameters) } }
然后可以像这样注入viewModel
class MainActivity : AppCompatActivity() { private val mAppViewModel: AppViewModel by appViewModel() }
此解决方案的优势在于,您无需重新创建视图模型,并且如果您决定在应用重启之间保存状态,您也可以轻松地将应用设置为SavedStateRegistryOwner,并使用SavedStateHandle从viewModel内部保存/恢复您的状态,现在已绑定到流程生命周期。
SavedStateRegistryOwner
SavedStateHandle
xa9qqrwz3#
我知道现在已经很晚了但你可以试试这个如果你要扩展一个baseViewModel,你需要将baseViewModel声明为single,然后在你各自的Activity中注入这个BaseViewModel。
single
val dataModule = module { single { BaseViewModel(get(), get()) } }
在视图模型中
class LoginViewModel(private val param: Repository, param1: Pref, param2: Engine) : BaseViewModel(param1, param2)
然后在活动课上
val baseViewModel: BaseViewModel by inject()
希望这对某人有所帮助。
xxls0lw84#
您必须在模块声明中使用single{}而不是viewModel{}。
single{}
viewModel{}
single { SharedViewModel() }
而且,您可以在视图中使用viewModel()。视图1
private val viewModel: SharedViewModel by viewModel()
视图2
但必须在视图开始时加载模块
loadKoinModules(module1)
重要的一点是,您必须在“何时销毁”视图中卸载模块。
unloadKoinModules(mainModule)
因此,当卸载模块时,您的单例ViewModel将被破坏。
#编辑
现在,您可以使用sharedViewModel声明。
z31licg05#
经过一些研究或讨论的架构水平,也报告和发布github Koin,我找到了解决方案在这种情况下,我们应该保存状态/数据到仓库,我们需要在多个活动之间共享不在视图模型和两个或更多不同的视图模型可以访问相同的状态/数据,保存在仓库的单个示例
5条答案
按热度按时间bz4sfanl1#
你需要阅读更多关于
ViewModel
的内容来更好地理解它。https://developer.android.com/topic/libraries/architecture/viewmodelViewModel
已连接到您的Activity
因此您只能在他
Fragments
之间共享您的ActivityViewModel
,这就是
koin
中sharedViewModel
含义如果将
ViewModel Factory
与相同的context
一起使用,则sharedViewModel
相同。在
Activities
之间共享任何数据都可以通过Intent
来完成,在Android中没有其他方法,或者您可以保留一些
static / global
数据,并在Activities
之间共享g6baxovj2#
我建议将应用程序设置为
ViewModelStoreOwner
,并注入viewModel,将其作为应用程序的所有者。您可以定义一些扩展来轻松地注入viewModel
然后可以像这样注入viewModel
此解决方案的优势在于,您无需重新创建视图模型,并且如果您决定在应用重启之间保存状态,您也可以轻松地将应用设置为
SavedStateRegistryOwner
,并使用SavedStateHandle
从viewModel内部保存/恢复您的状态,现在已绑定到流程生命周期。xa9qqrwz3#
我知道现在已经很晚了但你可以试试这个如果你要扩展一个baseViewModel,你需要将baseViewModel声明为
single
,然后在你各自的Activity中注入这个BaseViewModel。在视图模型中
然后在活动课上
希望这对某人有所帮助。
xxls0lw84#
您必须在模块声明中使用
single{}
而不是viewModel{}
。而且,您可以在视图中使用viewModel()。
视图1
视图2
但必须在视图开始时加载模块
重要的一点是,您必须在“何时销毁”视图中卸载模块。
因此,当卸载模块时,您的单例ViewModel将被破坏。
#编辑
现在,您可以使用sharedViewModel声明。
z31licg05#
经过一些研究或讨论的架构水平,也报告和发布github Koin,我找到了解决方案在这种情况下,我们应该保存状态/数据到仓库,我们需要在多个活动之间共享不在视图模型和两个或更多不同的视图模型可以访问相同的状态/数据,保存在仓库的单个示例