Android、MVVM:在 ViewModel 中调用 ContentResolver

Posted

技术标签:

【中文标题】Android、MVVM:在 ViewModel 中调用 ContentResolver【英文标题】:Android, MVVM: call ContentResolver in ViewModel 【发布时间】:2022-01-03 09:21:02 【问题描述】:

我目前正在将我的代码结构重构为 MVVM 设计模式。 在官方 android.com 文档 (https://developer.android.com/topic/libraries/architecture/viewmodel) 中,他们写道:

警告: ViewModel 必须绝不引用视图、生命周期或任何 可能包含对活动上下文的引用的类。

问题是,在我当前的代码中,我使用 ContentResolver 来查询手机上的联系人数据库。

var cursor: Cursor? = mainActivity.contentResolver.query(
        ContactsContract.Data.CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME
)

我想在 viewModel 代码中查询数据库,但看起来,ViewModel 没有 getContentResolver() 方法或类似的方法,我不允许将活动传递给 viewModel。如何从 viewModel 中访问数据库?有可能吗?

【问题讨论】:

您可以使用AndroidViewModel,它可以访问应用程序上下文。或者在需要时将应用程序上下文作为参数传递。您提到的警告更多的是关于不在 ViewModel 中使用或存储活动、视图、片段等,而不是真正关于使用任何类型的上下文。 This might help too @TylerV 非常感谢,AndroidViewModel 正是我所需要的!由于我偶然发现的系统服务访问问题,他们似乎设计了该子类。我希望他们在我阅读的任何文档中都包含了该信息...如果您将评论重新发布为答案,我会将其标记为已解决。 【参考方案1】:

如果您需要访问 ViewModel 中的上下文,可以使用 AndroidViewModel,它允许您使用 getApplication() 访问应用程序上下文。您可以使用它来获取 ContentResolver 之类的东西。

您列出的注意事项是关于不在 ViewModel 中使用或存储活动、片段、视图或其他生命周期组件 - 并不真正适用于应用程序上下文(有时需要获取字符串等内容,或者在您的情况下,ContentResolver,不绑定到视图生命周期)。

【讨论】:

以上是关于Android、MVVM:在 ViewModel 中调用 ContentResolver的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 上使用 MVVM 时,每个 Activity 是不是应该有一个(且只有一个)ViewModel?

Android mvvm框架之ViewModel

Android - MVVM 中 ViewModel 状态的最佳实践?

Android:MVVM 是不是可以显示来自 ViewModel 的消息(toast/snackbar 等)

Android : Kotlin : MVVM : 为啥 viewModel.onButtonClicked() 会导致应用程序崩溃?

Android MVVM-编程思想2(入门实战MVVM,DataBinding,ViewModel,LiveData)