跳转到内容

ContentProvider

来自代码酷

ContentProvider[编辑 | 编辑源代码]

ContentProvider是Android平台中的一个核心组件,它提供了一种标准化的接口,用于在不同应用程序之间共享数据。作为Android四大组件之一(其他三个是ActivityServiceBroadcastReceiver),ContentProvider封装数据并通过统一的URI机制提供访问权限控制。

基本概念[编辑 | 编辑源代码]

ContentProvider的主要特点包括:

  • 提供跨应用数据共享的安全机制
  • 使用URI(统一资源标识符)作为数据标识
  • 实现标准的数据访问接口(CRUD操作)
  • 支持数据变更通知机制

架构与工作原理[编辑 | 编辑源代码]

ContentProvider工作在客户端-服务器模式下: 1. 提供者应用:实现ContentProvider的子类并声明在清单文件中 2. 客户端应用:通过ContentResolver与提供者交互

graph LR A[客户端应用] -->|ContentResolver| B[ContentProvider] B --> C[(数据库/文件/网络)]

核心方法[编辑 | 编辑源代码]

ContentProvider类包含以下关键方法:

public class MyProvider extends ContentProvider {
    // 初始化Provider
    @Override
    public boolean onCreate() { ... }
    
    // 查询数据
    @Override
    public Cursor query(Uri uri, String[] projection, 
                       String selection, String[] selectionArgs,
                       String sortOrder) { ... }
    
    // 插入数据
    @Override
    public Uri insert(Uri uri, ContentValues values) { ... }
    
    // 更新数据
    @Override
    public int update(Uri uri, ContentValues values,
                     String selection, String[] selectionArgs) { ... }
    
    // 删除数据
    @Override
    public int delete(Uri uri, String selection, 
                     String[] selectionArgs) { ... }
    
    // 返回MIME类型
    @Override
    public String getType(Uri uri) { ... }
}

URI格式[编辑 | 编辑源代码]

ContentProvider使用特定格式的URI来标识数据:

content://<authority>/<path>/<id>

示例:

  • content://com.example.provider/contacts - 所有联系人
  • content://com.example.provider/contacts/1 - ID为1的联系人

实际应用示例[编辑 | 编辑源代码]

1. 实现简单的ContentProvider[编辑 | 编辑源代码]

public class BookProvider extends ContentProvider {
    private SQLiteDatabase mDb;
    
    @Override
    public boolean onCreate() {
        BookDatabaseHelper helper = new BookDatabaseHelper(getContext());
        mDb = helper.getWritableDatabase();
        return mDb != null;
    }
    
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                      String[] selectionArgs, String sortOrder) {
        return mDb.query("books", projection, selection, 
                        selectionArgs, null, null, sortOrder);
    }
    // 其他方法实现...
}

2. 在AndroidManifest.xml中声明[编辑 | 编辑源代码]

<provider
    android:name=".BookProvider"
    android:authorities="com.example.bookprovider"
    android:exported="true" />

3. 客户端访问示例[编辑 | 编辑源代码]

// 查询所有书籍
Cursor cursor = getContentResolver().query(
    Uri.parse("content://com.example.bookprovider/books"),
    null, null, null, null);

// 插入新书籍
ContentValues values = new ContentValues();
values.put("title", "Android开发指南");
values.put("author", "张三");
getContentResolver().insert(
    Uri.parse("content://com.example.bookprovider/books"), 
    values);

高级特性[编辑 | 编辑源代码]

数据变更通知[编辑 | 编辑源代码]

ContentProvider可以通过ContentResolver.notifyChange()方法通知注册的观察者数据已变更:

getContext().getContentResolver().notifyChange(uri, null);

客户端可以注册ContentObserver来监听变化:

getContentResolver().registerContentObserver(
    uri, true, new MyObserver());

批量操作[编辑 | 编辑源代码]

Android支持通过ContentProviderOperation进行批量操作:

ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ops.add(ContentProviderOperation.newInsert(uri)
      .withValue("title", "新书")
      .build());
getContentResolver().applyBatch(authority, ops);

安全考虑[编辑 | 编辑源代码]

  • 通过android:permission属性声明所需权限
  • 使用android:readPermission和android:writePermission分别控制读写权限
  • 对于敏感数据,设置android:exported="false"限制外部访问

常见系统ContentProvider[编辑 | 编辑源代码]

Android系统提供了多个内置ContentProvider:

  • ContactsContract - 联系人数据
  • CalendarContract - 日历数据
  • MediaStore - 多媒体文件
  • Settings - 系统设置

性能优化建议[编辑 | 编辑源代码]

1. 使用数据库索引优化查询性能 2. 对于大数据集,实现分页查询 3. 合理使用批量操作减少IPC调用 4. 考虑使用CursorLoader在后台线程加载数据

参见[编辑 | 编辑源代码]