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
相关产品推荐
相关产品推荐

