理解 ContentProvider 原理(一)

557 查看

基于Android 6.0源码剖析,本文涉及的相关源码:

一、概述

ContentProvider(内容提供者)用于提供数据的统一访问格式,封装底层的具体实现。对于数据的使用者来说,无需知晓数据的来源是数据库、文件,或者网络,只需简单地使用ContentProvider提供的数据操作接口,也就是增(insert)、删(delete)、改(update)、查(query)四个过程。

1.1 ContentProvider

ContentProvider作为Android四大组件之一,并没有Activity那样复杂的生命周期,只有简单地onCreate过程。ContentProvider是一个抽象类,当实现自己的ContentProvider类,只需继承于ContentProvider,并且实现以下六个abstract方法即可:

  • onCreate():执行初始化工作;
  • insert(Uri, ContentValues):插入新数据;
  • delete(Uri, String, String[]):删除已有数据;
  • update(Uri, ContentValues, String, String[]):更新数据;
  • query(Uri, String[], String, String[], String):查询数据;
  • getType(Uri):获取数据MIME类型。

1.2 Uri

从ContentProvider的数据操作方法可以看出都依赖于Uri,对于Uri有其固定的数据格式,例如:content://com.gityuan.articles/android/3

  • 前缀:默认开头content://;
  • 授权:唯一标识com.gityuan.articles;
  • 路径:指定数据类别以及数据项/android/3;

1.3 ContentResolver

其他app或者进程想要操作ContentProvider,则需要先获取其相应的ContentResolver,再利用ContentResolver类来完成对数据的增删改查操作,下面列举一个查询操作,查询得到的是一个Cursor结果集,再通过操作该Cursor便可获取想要查询的结果。

1.4 类图

content_provider

二、流程分析

接下来,从源码角度来说说,以数据查询query的为例来说说ContentProvider的整个完整流程。

2.1 相关成员变量

在开始源码分析之前,先说说涉及到的几个关于contentProvider的重要的成员变量。

2.1.1 AMS

  • CONTENT_PROVIDER_PUBLISH_TIMEOUT: 对于attached进程,用于publish该进程中的ContentProvider的超时时长为10s,超过10s则会被hung住。
  • CONTENT_PROVIDER_RETAIN_TIME: 保持ContentProvider所在进程的上次活动状态的持续时长为20s,当超过20s则运行其下降到正常的 cached LRU列表, 这样做的目的是为了避免在低内存情况下,ContentProvider所在进程发生波动。
  • mProviderMap:记录所有的contentProvider
  • mLaunchingProviders:记录所有的存在client等待其发布完成的contentProvider列表,一旦发布完成则相应的contentProvider便会从该列表移除;

2.1.2 ProcessRecord

  • pubProviders:记录进程中所有创建的ContentProvider;
  • conProviders:记录进程中所有使用的ContentProvider;

2.1.3 ActivityThread