You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android MVVM架构下如何在ViewModel中调用ContentResolver查询联系人数据库

Android MVVM模式下ViewModel访问ContentResolver查询联系人的实现方案

这个需求完全可以实现,核心逻辑是规避持有Activity这类短生命周期上下文,改用生命周期和应用进程一致的Application上下文来获取ContentResolver,完全符合官方对ViewModel的约束要求,具体实现方案如下:

  • 优先使用官方提供的AndroidViewModel类作为你的ViewModel父类:AndroidViewModel是ViewModel的原生子类,允许接收Application实例作为构造参数,Application上下文是全局生命周期,不会和Activity的销毁逻辑绑定,不会产生内存泄漏问题。
  • 在ViewModel内部直接通过Application实例获取ContentResolver执行查询即可,示例代码如下:
class ContactsViewModel(application: Application) : AndroidViewModel(application) {
    fun queryContacts(projection: Array<String>, selection: String?, selectionArgs: Array<String>?) {
        val cursor: Cursor? = getApplication<Application>().contentResolver.query(
            ContactsContract.Data.CONTENT_URI,
            projection,
            selection,
            selectionArgs,
            ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME
        )
        // 此处执行cursor数据解析、后续业务逻辑处理
        cursor?.close()
    }
}
  • 如果你需要做更彻底的架构分层解耦,可以把联系人查询逻辑封装到独立的Repository层,ViewModel仅调用Repository的暴露方法即可,进一步降低ViewModel和系统API的耦合度。

注意:不要将查询得到的Cursor直接传递到View层处理,建议在ViewModel或Repository层将Cursor内的数据解析为自定义业务实体类后再暴露给View层,避免View层持有Cursor引发资源泄漏,也符合MVVM的分层职责划分要求。

内容的提问来源于stack exchange,提问作者Jonathan Fenno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 10:54:03