android 如何使用Koin DI在Activity之间共享相同的ViewModel示例?

y4ekin9u  于 2022-11-03  发布在  Android
关注(0)|答案(5)|浏览(284)

我在Kotlin中使用Koin库进行DI
Koin提供by viewmodel(),用于获取ViewModel by sharedViewModel()的示例,以获取片段中的相同示例。
如何在活动中获得相同的ViewModel示例?我没有找到任何方法来实现这一点。

bz4sfanl

bz4sfanl1#

你需要阅读更多关于ViewModel的内容来更好地理解它。https://developer.android.com/topic/libraries/architecture/viewmodel
ViewModel已连接到您的Activity
因此您只能在他Fragments之间共享您的ActivityViewModel
这就是koinsharedViewModel含义
如果将ViewModel Factory与相同的context一起使用,则sharedViewModel相同。
Activities之间共享任何数据都可以通过Intent来完成,在Android中没有其他方法,
或者您可以保留一些static / global数据,并在Activities之间共享

g6baxovj

g6baxovj2#

我建议将应用程序设置为ViewModelStoreOwner,并注入viewModel,将其作为应用程序的所有者。

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内部保存/恢复您的状态,现在已绑定到流程生命周期。

xa9qqrwz

xa9qqrwz3#

我知道现在已经很晚了但你可以试试这个如果你要扩展一个baseViewModel,你需要将baseViewModel声明为single,然后在你各自的Activity中注入这个BaseViewModel。

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()

希望这对某人有所帮助。

xxls0lw8

xxls0lw84#

您必须在模块声明中使用single{}而不是viewModel{}

single { SharedViewModel() }

而且,您可以在视图中使用viewModel()。
视图1

private val viewModel: SharedViewModel by viewModel()

视图2

private val viewModel: SharedViewModel by viewModel()

但必须在视图开始时加载模块

loadKoinModules(module1)

重要的一点是,您必须在“何时销毁”视图中卸载模块。

unloadKoinModules(mainModule)

因此,当卸载模块时,您的单例ViewModel将被破坏。

#编辑

现在,您可以使用sharedViewModel声明。

z31licg0

z31licg05#

经过一些研究或讨论的架构水平,也报告和发布github Koin,我找到了解决方案在这种情况下,我们应该保存状态/数据到仓库,我们需要在多个活动之间共享不在视图模型和两个或更多不同的视图模型可以访问相同的状态/数据,保存在仓库的单个示例

相关问题