如何编写使用 Context 从 Android 框架检索数据的用例

Ben*_*nyP 5 android use-case mvvm clean-architecture android-mvvm

我正在将一个应用程序迁移到 MVVM 和干净的架构,但我遗漏了这个难题的一部分。

问题域:

列出设备上的所有应用程序并将其显示在 Fragment / Activity 中

设备应用程序由其包名称表示:

data class DeviceApp(val packageName: String)

设备应用程序的列出方式如下:

private fun listAllApplications(context: Context): List<DeviceApp> {
    val ans = mutableListOf<DeviceApp>()

    val packageManager: PackageManager = context.applicationContext.packageManager
    val packages = packageManager.getInstalledApplications(PackageManager.GET_META_DATA)
    for (applicationInfo in packages) {
        val packageName = applicationInfo.packageName
        ans.add(DeviceApp(packageName))
    }

    return ans
}
Run Code Online (Sandbox Code Playgroud)

据我了解,调用listAllApplications()应该在“域层”内的用例中完成,该用例由ViewModel.

但是listAllApplications收到一个Context, 并且域层应该只是纯代码。

在干净的架构/MVVM 中,我应该放在哪一层listAllApplications(context)?

更一般地说,ViewModel 应如何与需要Context(位置等)的 Android 框架 API 进行交互?

Jee*_*ede 3

域层应该只是纯代码。

没错!,但在我看来这是部分正确的。现在考虑您context在域级别所需的场景。您不应该context在域级别,但根据您的需要,您应该选择其他架构模式,或者将其视为您正在这样做的特殊情况。

考虑到您在域中使用上下文,您应该始终使用applicationContext尽管activity context,因为早期在整个过程中仍然存在。

ViewModel 应该如何与需要 Context(位置等)的 Android 框架 API 进行交互?

每当您需要ContextViewModel 时,您可以从 UI 作为方法参数(即viewModel.getLocation(context))提供它,或者用作AndroidViewModel您的父类ViewModel (它提供getApplication()公共方法来通过 ViewModel 访问上下文)。

我想指出的是,确保您不会意外地在 ViewModel/Domain Layer 内全局保存任何 View/Context,因为它可能会导致内存泄漏或崩溃等灾难,更糟糕的是。