Android四大组件总结——ContentProvider

Android四大组件总结——ContentProvider

ContentProvider是Android四大组件之一,主要用于在不同应用间实现数据共享的功能。是Android实现跨程序共享数据的标准方式。

ContentProvider的基本使用

ContentProvider一般有两种用法,一种是用现有的ContentProvider来读取与操作相应程序的数据。另一种是创建自己的ContentProvider给程序的数据提供外部访问的接口。如果一个程序通过ContentProvider对它的数据提供了外部访问接口,则任何其他程序都可以对此部分数据进行访问。

读取数据:ContentResolver的使用

要访问ContentProvider中共享的内容,一般都会用到ContentResolver类。可以通过Context的getContentResolver()方法来获取该类的实例。其中提供了一系列方法来对数据进行增删查改。

与SQLite不同的是,ContentProvider的增删查改并不是接收表名参数,而是用内容URI。

内容URI

内容URI主要由两部分组成,authority与path。比如一个包名为com.android.test的app,它的authority就可以命名为com.android.test.provider。path是对一个应用程序不同的表做区分的,通常添加到authority的后面。如某个程序数据库中有两个表table1和table2,这时path就可以是/table1或者/table2。authority与path组合后,在头部加上协议声明后,就是一个标准的内容URI了。如:

content://com.android.test.provider/table1*

*content://com.android.test.provider/table2

得到内容URI字符串后,通过Uri类的parse方法即可将其解析为Uri对象了。

Uri uri = Uri.parse("content://com.android.test.provider/table1");

如果要访问的是table表中id为1的数据,可以通过uri后加上/id来实现。如:

Uri uri = Uri.parse("content://com.android.test.provider/table1/1");

Uri中还有两种通配符:

  • *****:表示匹配任意长度的任意字符。
  • #:表示匹配任意长度的数字。

我们可以用它们来达成查询任意表或某张表任意一条数据的效果

表示匹配任意表的内容的Uri:content://com.android.test.provider/*

表示table1表中任意一行的内容的Uri:content://com.android.test.provider/table1/#

查询数据

有了Uri后,我们只需要用它来进行查询就好了。查询后返回的是一个Cursor对象,然后我们就可以将数据从Cursor中逐个取出了。

Cursor cursor = getContentResolver().query(
	uri,
	projection,
	selection,
	selectionArgs,
	sortOrder);

这些参数和SQLite中的参数有点相似。用SQL语句来举例的话,它们都有各自对应的部分

参数名对应SQL部分
urifrom table_name
projectionselect column1, column2
selectionwhere column = value
selectionArgs-
sortOrderorder by column1, column2
添加数据

添加数据就很简单了,构造一个ContentValues,然后用insert方法将它插入就好。

ContentValues values = new ContentValues();
values.put("column1","text");
values.put("column2",1);
getContentResolver().insert(uri,values);
更新数据

更新数据也是非常简单的

ContentValues values = new ContentValues();
values.put("column1","");
getContentResolver().update(uri,values,"column1 = ? and column2 = ?", new String[]{
"text","1"});
删除数据

一样很简单

getContentResolver().update(uri,"column2 = ?",new String[]{"1"});

提供数据:ContentProvider的创建

如果想要在自己的应用中为外部提供接口来达到共享数据的目的,可以新建一个类继承ContentProvider,并重写它的六个抽象方法

  1. onCreate:初始化ContentProvider的时候调用,通常在这里进行数据库的创建和升级。返回true表示ContentProvider初始化成功,返回false则表示失败。
  2. query:从ContentProvider中查询数据,查询的结果存放在Cursor中返回。
  3. insert:向ContentProvider添加一条数据,返回用于表示这条新纪录的Uri。
  4. update:更新ContentProvider已有的数据,返回受影响的行数。
  5. delete:从ContentProvider中删除不数据。返回被删除的行数。
  6. getType:根据传入的Uri返回相应的MIME类型。
UriMatcher

我们可借助UriMatcher来轻松实现匹配内容Uri的功能。它提供了addURI方法,可分别把authority、path以及一个自定义代码传进去。这样,调用UriMatcher的match()方法时,就能传入一个Uri对象,返回匹配这个对象的自定义代码了。利用这个代码,我们就可以判断调用方希望访问哪张表的数据了。

public static final int TABLE1_DIR = 0; 
public static final int TABLE1_ITEM = 1; 
public static final int TABLE2_DIR = 2; 
public static final int TABLE2_ITEM = 3; 
public static 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);    
}
实现增删查改方法

比如,我们可以用如下的方法来实现query方法:

@Override
public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder){
    switch(uriMatcher.match(uri)){
        case TABLE1_DIR:
            //查询table1表的所有数据
            break;
        case TABLE1_ITEM:
            //查询table1表的单条数据
            break;
        case TABLE2_DIR:
            //查询table2表的所有数据
            break;
        case TABLE2_ITEM:
            //查询table2表的单条数据
            break;
            ...
    }
    ...
}

除此之外,insert, update, delete这几个方法的实现也是差不多的。

实现getType方法

除增删查改方法外有一个方法需要注意,就是getType方法。它是所有ContentProvider都需要提供的方法,用于获取Uri对象对应的MIME类型。

MIME类型

一个内容URI所对应的MIME字符串主要由三部分组成:

  • 必须以vnd开头
  • 如果内容URI以path结尾,则后接android.cursor.dir/ ,如果以id结尾,则后接android.cursor.item/
  • 最后接上vnd..

因此对于content://com.android.test.provider/table1这个内容Uri,它对应的MIME类型可以写成:

vnd.android.cursor.dir/vnd.com.android.test.provider.table1

对于content://com.android.test.provider/table1/1这个内容Uri,对应的MIME类型就可以写成:

vnd.android.cursor.item/vnd.com.android.test.provider.table1

实现getType方法

有了MIME类型的概念后,我们可以这样实现getType方法:

@Override
public String getType(Uri uri){
    switch(uriMatcher.match(uri)){
        case TABLE1_DIR:
        	return "vnd.android.cursor.dir/vnd.com.android.test.provider.table1";
       	case TABLE1_ITEM:
        	return "vnd.android.cursor.item/vnd.com.android.test.provider.table1";
        case TABLE2_DIR:
        	return "vnd.android.cursor.dir/vnd.com.android.test.provider.table2";
        case TABLE1_ITEM:
        	return "vnd.android.cursor.item/vnd.com.android.test.provider.table2";
        default:
        	break;
    }
    return null;
}
用数据库配合上述方法

一般创建ContentProvider都要配合这个应用的数据库,配合数据库的使用一般是这样的:

  • 在onCreate方法中建立数据库
  • 分别在query insert update delete方法中调用SQLiteDatabase的同名方法来实现。

广告时间
我是N0tExpectErr0r,一名广东工业大学的大二学生
欢迎来到我的个人博客,所有文章均在个人博客中同步更新哦
http://blog.N0tExpectErr0r.cn

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值