Android基础篇-四大组件之使用ContentProvider实现数据共享

ContendProvider是不同应用程序之间进行数据交换的标准API,ContentProvider以某种Uri的形式对外提供数据,允许其他应用访问或修改数据;其他应用程序使用ContentReslover根据Uri去访问操作指定数据

因为ContendProvider是四大组件之一,所以也需要在清单文件配置:

<!--下面配置中name属性指定ContentProvider类,
authorities就相当于为该ContentProvider指定域名
exported指定该ContentProvider是否允许其他程序调用-->
<provider android:name=".*****" 
    android:authorities="*****"
    android:exported="true"/>

Uri简介:Uri就是应用之间通过CotentProvider访问数据的一个标识
,应用之间标识一致才能访问
它分为如下三个部分:
1.content:// 这个部分是协议默认的,必须打头写的
2.这个部分就是ContentProvider的authorities,就是由这个部分来找到操作那个ContentProvider的,只要访问指定的ContentProvider这个部分就是固定的
3.words:资源部分(或者说数据部分)当访问者需要访问不同资源时,这个部分就是动态改变的

ContentProvider的作用:是暴露可供操作的数据;其他应用程序则通过ContentResolver来操作ContentProvider暴露的数据。
Context提供getContentResolver来获取ContentResolver对象

开发ContentProvider子类

public class FirstProvider extends ContentProvider
{
   //第一次创建该ContentProvider时调用该方法
   @Override
   public boolean onCreate()
   {
       System.out.println("===onCreat方法被调用====");
       return true;
   }
   //该方法的返回值代表了该ContentProvider所提供数据的MIME类型
   @Override
   public String getType(Uri uri)
   {
       return null;
   }
   //实现查询方法,该方法应该返回查询得到的Cursor
   @Override
   public Cursor qurey(Uri uri,String[] projection,String where, String[] whereArgs,String sortOrder)
   {
       System.out.println(uri+"===query方法被调用====");
       System.out.println("where参数为:"+where);
       return null;
   }
   //实现插入的方法,该方法应该返回新插入的记录的Uri
   @Override
   public Uri insert(Uri uri,ContentValues values)
   {
       System.out.println(uri+"===insert方法被调用====");
       System.out.println("values参数为:"+values);
       return null;
   }
   //实现更新方法,该方法应该返回被更新的记录条数
   @Override
   public int update(Uri uri,ContentProvider values,String where,String[] whereArgs)
   {
       System.out.println(uri+"===update方法被调用====");
       System.out.println("where参数为:"+where+",values参数为:"+values);
       return 0;
   }
   //实现删除方法,该方法返回被删除的记录条数
   @Override
   public int delete(Uri uri,String where ,String[] whereArgs)
   {
       System.out.println(uri+"===delete方法被调用====");
       System.out.println("where参数为:"+where);
       return 0;
   }
}

创建ContentProvider说明
1.关于生命周期
ContentProvider只有一个onCreate()生命周期方法,当其他应用通过ContentResolver第一次访问ContentProvider时,onCreate()将会被调用,且只会被调用一次;ContentProvider提供的query(),insert(),update(),delete()方法则由其他应用通过ContentResolver调用

**URiMatcher:**为了确定该ContentProvider实际能处理的Uri,以及确定每个方法中Uri参数所操作的数据所产生的工具类
主要有两个方法:
1.void addURI(String authority,String path,int code):该方法用于向UriMatcher对象注册Uri,其中authority和path组合成一个Uri,而code则代表该Uri对应的标识码。
2.int mathc(Uri uri):根据前面注册的Uri来判断指定Uri对应的标识码。如果找不到匹配的标识码,该方法将会返回-1.

/** 一个标识码对应的是1,一个对应的是2
 *  至于到底需要为UriMatcher对象注册多少个Uri,则取决于系统的业务需
 *  求。
 */
UriMatcher matcher=new Urimatcher(UriMatcher.NO_MATCH);
//
matcher.addURI("*****","words",1);
matcher.addURI("*****","word/#",2);
//返回标识码1
matcher.match(Uri.parse("content://*****/words"));
//返回标识码2
matcher.match(Uri.parse("content://*****/word/2"));
//返回标识码2
matcher.match(Uri.parse("content://*****/word/10"));

**ContentUris:**它是一个操作Uri字符串的工具类,提供了如下两个工具方法:
1.withAppendedId(uri,id):用于为路径加上ID部分,例如:

Uri uri=Uri.parse("content://com.example.teacher/word")
Uri resultUri=ContentUris.withAppendId(uri,2);
//生成后的Uri为"content://com.example.teacher/word/2"

2.parseId(uri):用于从指定Uri解析出所包含的ID值。例如:

Uri uri=Uri.parse("content://com.example.teacher/word/2");
long wordId=ContentUris.parseId(uri);//获取的结果为2

ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,contenvalues只能存储基本类型的数据,像string,int之类的,不能存储对象这种东西,而HashTable却可以存储对象。

在忘数据库中插入数据的时候,首先应该有一个ContentValues的对象所以:

ContentValues initialValues = new ContentValues();

initialValues.put(key,values);

SQLiteDataBase sdb ;

sdb.insert(database_name,null,initialValues);

插入成功就返回记录的id否则返回-1;

Android本身就提供了大量的ContentProvider,下面是常用的Uri:

1.ContactsContract.Contacts.CONTENT_URI:管理联系人的Uri.
2.ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理联系人的电话的Uri.
3.ContactsContract.CommonDataKinds.Email.CONTENT_URI:管理联系人的E-mail的Uri.
4,MediaStroe.Audio.Media.EXTERNAL_CONTENT_URI:存储在外部存储器上的音频文件内容的ContentProvider的Uri;
5.MediaStroe.Audio.Media.INTERNAL_CONTENT_URI:存储在手机内部存储器上的音频文件内容的ContentProvider的Uri.
6.MediaStore.Images.Media.EXTERNAL_CONTENT_URI:存储在外部存储器上的图片文件内容的ContentProvider的Uri.
7.MediaStore.Images.Media.INTERNAL_CONTENT_URI:存储在手机内部存储器上的图片文件内容的ContentProvider的Uri.
8.MediaStore.Video.Media.EXTERNAL_CONTENT_URI:存储在外部存储器上的图片文件内容的ContentProvider的Uri.
9.MediaStore.Images.Media.INTERNAL_CONTENT_URI:存储在手机内部存储器上的图片文件内容的ContentProvider的Uri.

**ContentObserver:**用于监听ContentProvider所共享的数据的改变提供响应。
其实只要导致ContentProvider数据的改变就回调用如下代码:

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

为了在应用程序监听ContentProvider数据的改变,需要利用Android提供的ContentObserver基类,继承它并重写onChange(boolean selfChange)方法,当它所监听的ContentProvider数据发生改变时,就会触发onChange(boolean selfChange)方法。

为了监听指定ContentProvider的数据变化,需要通过ContentProvider向指定Uri注册ContentObserver监听器。ContentResolver提供了如下方法来注册监听器:
registerContentObserver(Uri uri,boolean notifyForDescendents,ContentObserver observer)
uri:该监听器所监听的ContentProvider的Uri,
notifyForDescendents:如果该参数设为true,假如注册监听的Uri为content://abc,那么Uri为content://abc/xyz、content://abc/xyz/zoo的数据改变时也会触发该监听器。如果该参数设为不false,假如注册监听的Uri为content://abc,那么只有content://abc的数据发生改变时才会触发该监听器。
**observer:**监听器实例

掌握以上只是基本就掌握了,只是还是需要实际动手操作一番。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有头发的猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值