基础概念
1. 本质与作用
- 定义:Android 中实现跨应用数据共享的核心组件,封装数据访问接口,允许不同应用间安全地读写数据。
- 核心场景:系统应用(如联系人、短信)的数据共享,或自定义应用间的数据交互(如相册、文件管理)。
- 与其他组件的关系 :通过
ContentResolver与外部交互,底层依赖Binder实现跨进程通信。
2. 核心术语与架构
-
URI(Uniform Resource Identifier) :唯一标识数据的路径,格式为
content://authority/path(如content://com.example.contacts/people)。authority:应用包名(如com.example),用于标识 ContentProvider 的所有者。path:数据路径(如people表示联系人表)。
-
ContentProvider vs ContentResolver vs ContentObserver:
ContentProvider:数据提供者,封装数据操作逻辑。ContentResolver:数据访问接口,供外部应用通过 URI 操作数据。ContentObserver:监听数据变化的观察者,数据更新时触发回调。
ContentProvider 核心类与接口
1. 必知核心类
-
ContentProvider(抽象类) :
-
必须实现的方法:
onCreate()、query()、insert()、update()、delete()、getType()。 -
示例:
javapublic class MyContentProvider extends ContentProvider { @Override public boolean onCreate() { /* 初始化数据源(如SQLiteOpenHelper)*/ } // 其他方法实现... }
-
-
ContentResolver:
- 常用方法:
query()、insert()、update()、delete()、registerContentObserver()。
- 常用方法:
-
ContentUris :辅助类,用于操作 URI(如
withAppendedId(uri, id)生成带 ID 的 URI)。
2. URI 解析与 MIME 类型
-
URI 解析 :使用
UriMatcher匹配不同 URI 路径,示例:javaUriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); matcher.addURI("com.example", "people", PEOPLE_DIR); matcher.addURI("com.example", "people/#", PEOPLE_ITEM); -
MIME 类型 :通过
getType(uri)返回,格式为vnd.android.cursor.dir/(集合)或vnd.android.cursor.item/(单个),如vnd.android.cursor.dir/people。
生命周期与基本用法
1. 生命周期流程
onCreate():组件创建时调用,用于初始化数据源(如数据库)。- 其他方法(
query/insert等):由 ContentResolver 触发,在主线程执行,需注意耗时操作(建议异步处理)。
2. 自定义 ContentProvider 步骤
-
继承
ContentProvider并实现抽象方法。 -
在
AndroidManifest.xml中注册,声明authorities和权限:xml<provider android:name=".MyContentProvider" android:authorities="com.example.myprovider" android:exported="true" android:grantUriPermissions="true" android:readPermission="com.example.READ_PERMISSION" android:writePermission="com.example.WRITE_PERMISSION" /> -
外部应用通过
ContentResolver访问,示例:javaUri uri = Uri.parse("content://com.example.myprovider/people"); Cursor cursor = getContentResolver().query(uri, null, null, null, null);
数据共享与权限控制
1. 跨应用数据共享机制
- 核心原理:通过 URI 屏蔽数据源细节(SQLite、文件等),外部应用无需知道数据存储方式。
- 典型案例 :系统联系人应用的
ContactsContract提供标准 URI 接口。
2. 权限管理
- 声明式权限 :通过
android:readPermission和android:writePermission控制访问。 - 临时权限 :通过
ContentResolver.grantUriPermission()授予其他应用临时 URI 访问权(如文件选择器场景)。 - 基于 URI 的细粒度权限 :通过
android:grantUriPermissions="true"配合Intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION)实现。
实际应用场景
1. 系统 ContentProvider 案例
- 联系人(ContactsContract) :URI 为
content://com.android.contacts/contacts。 - 媒体文件(MediaStore) :管理相册、音频、视频等,如
MediaStore.Images.Media.EXTERNAL_CONTENT_URI。 - 短信(Telephony.Sms) :Android 4.4 + 通过
content://sms/访问(需特殊权限)。
2. 自定义应用场景
- 多模块数据共享:同一应用内不同模块通过 ContentProvider 解耦。
- 跨应用数据同步:如笔记应用与桌面小组件通过 ContentProvider 共享数据。