Content Provider 组件详解

        在Android系统中四大组件中,最复杂的莫过于Content Provider 。今天我们来一起探讨一下这个组件。

      我们知道在访问数据的时候,我们可以将数据以不同形式存储在文件中(例如:数据库,文件系统,图片等)。但是我们的存储格式不一样则会影响数据的读取。怎么办呢,Android系统中为我们提供了一种方式:进行数据的共享,并统一采用数据操作方式进行处理。这个就是Content Provider组件了。我们来讲讲如何使用这个组件。

     1.我们需要进行数据共享的时候,首先要继承ContentProvider组件:

  public class StudentContentProvider extends ContentProvider{
   public boolean onCreate()
   public Uri insert(Uri uri, ContentValues values)
   public int delete(Uri uri, String selection, String[] selectionArgs)
   public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
   public String getType(Uri uri)
}

   2.在AndroidManifest.xml文件中去注册一下就可以使用了,这么注册的时候一定要注意authorities(域名或者主机名)。这个一定要在Android的系统中是唯一的,要不然会出现问题。为了防止冲突,最简单的方式就是使用我们的域名进行。

   <manifest.... >
   <application android:icon="@drawable/icon" android:label="@string/app_name">
      <provider android:name=".StudentContentProvider" 
           android:authorities="sevenkj.net.csdn.blog.StudentContentProvider"/>
   </application>
</manifest>

    以上的两个步骤,我们的ContentProvider组件就已经做好了,那么他是在什么时候进行共享的呢?我们在安装应用程序的时候就会存在了,当我们卸载的时候它也会跟着被卸载掉。

    现在新问题来了,如何调用这个组件呢 ? 我们在做这个之前,先认识一下Uri。这个叫统一资源标识符,是用于代表需要操作的数据。两部分:需要操作的ContentProvider,ContentProvider的哪个数据进行操作。


ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://sevenkj.net.csdn.blog.StudentContentProvider/Student")

  

      UriMatcher

      我们需要对Uri的数据进行解析,我们才知道我们需要进行的操作数据。Android系统中提供了:UriMatcher和ContentUri。具体操作如下(一般我们是在操作ContentProvider 的时候,进行比配):

//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://sevenkj.net.csdn.blog.StudentContentProvider/Student路径,返回匹配码为1
sMatcher.addURI("sevenkj.net.csdn.blog.StudentContentProvider", "Student", 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://sevenkj.net.csdn.blog.StudentContentProvider/Student/230路径,返回匹配码为2
sMatcher.addURI("sevenkj.net.csdn.blog.StudentContentProvider", "Student/#", 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://sevenkj.net.csdn.blog.StudentContentProvider/Student/12"))) { 
   case 1
     break;
   case 2
     break;
   default://不匹配
     break;
}

       ContentUri主要包括两个方   法:withAppendedId(uri, id)和ParseId(uri)。第一个是在Uri的基础上添加ID的信息。第二个是根据Uri获取Id信息。

Uri uri = Uri.parse("content://sevenkj.net.csdn.blog.StudentContentProvider/Student")
Uri resultUri = ContentUris.withAppendedId(uri, 12); 
//生成后的Uri为:content://sevenkj.net.csdn.blog.StudentContentProvider/Student/12
Uri uri = Uri.parse("content://sevenkj.net.csdn.blog.StudentContentProvider/Student/12")
long personid = ContentUris.parseId(uri);//获取的结果为:12

     好了,到目前为止ContentProvider 所有情况都完了,那么我们如何在我们的服务或者Activity中调用这个呢?

Android系统为我们提供了一个叫ContentResolver。这里对应的查询、新增、修改、删除方法对应着我们在ContentProvider的方法,我们对应调用的时候,他就会对应到ContentProvider中去调用。


ContentResolver resolver =  getContentResolver();
Uri uri = Uri.parse("content://sevenkj.net.csdn.blog.StudentContentProvider/Student");
//添加一条记录
ContentValues values = new ContentValues();
values.put("Name", "seven");
values.put("Age", 25);
resolver.insert(uri, values);  
//获取person表中所有记录
Cursor cursor = resolver.query(uri, null, null, null, "Id desc");
while(cursor.moveToNext()){
   Log.i("ContentTest", "Id="+ cursor.getInt(0)+ ",Name="+ cursor.getString(1));
}
//把id为1的记录的name字段值更改新为seven
ContentValues updateValues = new ContentValues();
updateValues.put("name", "seven");
Uri updateIdUri = ContentUris.withAppendedId(uri, 12);
resolver.update(updateIdUri, updateValues, null, null);
//删除id为12的记录
Uri deleteIdUri = ContentUris.withAppendedId(uri, 12);
resolver.delete(deleteIdUri, null, null);

    应该大家都明白了吧,后续我们在具体的代码中去说明。

      





   



         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值