7-3 创建自己的 ContentProvider

一、创建 ContentProvider

  1. 创建类继承 ContentProvider

  2. 重写继承的 6 个抽象方法

  • onCreate()
	// 初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,
   // 返回true表示内容提供器初始化成功,返回false则表示失败。
   @Override
   public boolean onCreate() {
   
       return false;
   }
  • query()
 /**
     * 从内容提供器中查询数据
     *
     * @param uri           uri参数来确定查询哪张表
     * @param projection    用于确定查询哪些列
     * @param seletion      用于约束查询哪些行
     * @param selectionArgs
     * @param sortOrder     用于对结果进行排序
     * @return              查询的结果存放在Cursor对象中返回
     */
    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String seletion, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
   }
  • insert()
/**
     * 向内容提供器中添加一条数据
     *
     * @param uri               uri参数来确定要添加到的表
     * @param contentValues     待添加的数据保存在values参数中
     * @return                  返回一个用于表示这条新记录的URI
     */
    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
   
        return null;
    }
  • delete()
/**
     * 从内容提供器中删除数据
     *
     * @param uri               uri参数来确定删除哪一张表中的数据
     * @param selection         用于约束删除哪些行
     * @param selectionArgs
     * @return                  被删除的行数将作为返回值返回
     */
    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
   
        return 0;
    }
  • update()
/**
     * 更新内容提供器已有的数据
     *
     * @param uri               使用 uri 参数来确定更新哪一张表中的数据
     * @param contentValues     新数据保存在values参数中
     * @param selection         用于约束更新哪些行
     * @param selectionArgs     用于约束更新哪些行
     * @return                  受影响的行数将作为返回值返回
     */
    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String selection, @Nullable String[] selectionArgs) {
   
        return 0;
    }
  • getType()
/**
     * 根据传入的内容 URI 来返回相应的 MIME 类型。
     * MIME 类型:
     * 例如:
     * 1、Uri 为 cotent://com.example.app.provider/table1
     * 则对应的 MIME 类型为:vdn.android.cursor.dir/vdn.com.example.app.provider.table1
     *
     * 2、Uri 为 cotent://com.example.app.provider/table1/1
     * 则对应的 MIME 类型为:vdn.android.cursor.item/vdn.com.example.app.provider.table1
     *
     * @param uri
     * @return 返回 MIME 类型
     */
    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
   
    	return null;
    }

Uri 参数:

相当于数据库 CRUD 操作中传入的表名,指明要访问哪个程序的哪个数据库文件

这个参数由两个部分组成 authoritypath

  • authority 用于对不同应用程序进行区分,为避免冲突,一般用应用程序包名
  • path 对同一应用程序中不同的表进行区分,添加到 authority的后面
  • 字符串头部添加协议声明,以区分普通字符串和内容 Uri 字符串
  • 示例:
1、路径结尾:表示调用方期望访问该表中的全部数据
"content://com.example.app.provider/table1"
"content://com.example.app.provider/table2"

2、id 结尾:表示调用方期望访问该表中拥有相应 Id 的数据
"content://com.example.app.provider/table1/1"

Uri 参数示意图
可见,内容URI可以非常清楚地表达出我们想要访问哪个程序中哪张表里的数据。也正是因此,ContentResolver中的增删改查方法才都接收Uri对象作为参数,因为如果使用表名的话,系统将无法得知我们期望访问的是哪个应用程序里的表。

示例中的字符串目前也还只是单纯的字符串而已,要经过解析才能成为真正的 Uri 对象进行参数传递。

解析字符串:

Uri uri = Uri.prase("content://com.example.app.provider/table1");

getType() 方法中返回的 MIME 类型

  • 该方法根据传入的内容 URI 来返回相应的 MIME 类型。
  • 不同于 URI authority / path,MIME类型以 authority . path 结尾
1、路径结尾的内容 URI
例如:
content://com.example.app.provider/table1
对应的 MIME 类型为:
"vnd.android.cursor.dir/vnd.com.example.app.provider.table1"

1Id 结尾的内容 URI
例如:
content://com.example.app.provider/table1/1
对应的 MIME 类型为:
"vnd.android.cursor.item/vnd.com.example.app.provider.table1"

解析请求内容的 Uri

  • 创建我们自己的 ContentProvider需要对调用方传过来的 uri参数进行解析,从中分析出调用方希望访问的表。
1、解析 路径 结尾格式的内容 Uri,使用通配符 *,能够匹配任意表的内容 URI 格式
   "content://com.example.app.provider/*""content://com.example.app.provider"

2、解析 Id 结尾格式的内容 Uri,使用通配符 #,匹配 table1 表中任意一行数据的内容 URI 格式
"content://com.example.app.provider/table1/#"

UriMatcher 类

实现匹配内容 Uri 的功能

addURI()方法

  • 保存可以匹配的 Uri 类型
  • 3 个参数:authoritypath自定义代码(自定义代码用于和传入的 URI 进行匹配,匹配成功则返回对应类型的自定义代码)
// 访问 table1 表中所有的数据
    public static final int TABLE1_DIR = 0;
    // 访问 table1 表中的单条数据
    public static final int TABLE1_ITEM = 1;
    // 访问 table2 表中所有的数据
    public static final int TABLE2_DIR = 2;
    // 访问 table2 表中的单条数据
    public static final int TABLE2_ITEM = 3;
    private static final UriMatcher uriMatcher;

    static {
   
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
        uriMatcher.addURI("com.example.app.provider", "table1/#", TABLE1_ITEM);
        uriMatcher.addURI("com.example.app.provider", "table2", TABLE2_DIR);
        uriMatcher.addURI("com.example.app.provider", "table2/#", TABLE2_ITEM);
    }

match() 方法

  • 用于和已保存的可解析的 URI格式进行匹配,即 addURI()方法中添加的那些 URI,匹配成功则返回 addURI()中对应条目的自定义代码,然后我们就知道调用方具体想访问什么数据。
  • 常在增删改查中使用
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String seletion, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
   
        // 对传入的 uri 进行匹配,update(), insert(), delete(),相似
        switch (uriMatcher.match(uri)) {
   
            case TABLE1_DIR:
                // 查询 table1 表中所有的数据
                break;
            case TABLE1_ITEM:
                // 查询 table1 表的单条数据
                break;
            case TABLE2_DIR:
                // 查询 table1 表中所有的数据
                break;
            case TABLE2_ITEM:
                // 查询 table1 表中的单条数据
                break;
            default:
                break;
        }
        return null;
    }

二、代码示例

public class MyProvider extends ContentProvider {
   
    // 访问 table1 表中所有的数据
    public static final int TABLE1_DIR = 0;
    // 访问 table1 表中的单条数据
    public s
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值