Android-ContentProvider

一、概述

      当某个应用需要提供数据给其他应用时,它就要继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享它的数据了。

虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同(如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据)。而使用ContentProvider共享数据的好处是统一了数据访问方式。

 

      补充:要了解ContentProvider,需要从提供者和解析者两方面进行探究。

 

二、提供者的应用

      关键点1、继承ContentProvider内容提供者对象

关键点2、实现ContentProvider的如下方法(供内容解析者应用调用):

(1)public int delete(Uri uri, String selection, String[] selectionArgs)

解释:该方法在ContentProvider创建后就会被调用, Android开机后, ContentProvider在其它应用第一次访问它时才会被创建。

 

(2)public String getType(Uri uri)

解释:该方法用于供外部应用往ContentProvider添加数据。

 

(3)public Uri insert(Uri uri, ContentValues values)

解释:该方法用于供外部应用从ContentProvider删除数据。

 

(4)public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder)

解释:该方法用于供外部应用更新ContentProvider中的数据。

 

(5)public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs)

解释:该方法用于供外部应用从ContentProvider中获取数据。


关键点3、在AndroidMainfest.xml中对ContentProvider进行注册。

<provider

android:name = “包名.该类的名

android:authorities = “域名路径” >

</provider>

例如:

<provider

android:name = “com.sqb.MyProvider”

android:authorities = “com.a.b” >

</provider>

 

关键点4、创建共享的数据(一般是SQLite数据库里的数据)

解释:这个应用应当创建一个数据库,获取到SQLiteOpenHelper对象,然后对数据库的增删改查操作分别放到ContentProvider的实现方法里面。

 

关键点5、Uri

解释:详细请看http://blog.csdn.net/dmk877/article/details/50387741

(1)用Uri的静态方法parse将路径字符串转化为内容解析者所识别的Uri,只有当内容解析者提供符合内容提供者定义的Uri调用增删改查的方法才有效。

例如:Uri uri = Uri.parse("content://" +”com.a.b”+ "/student")


关键点6UriMatcher

解释: UriMatcher 类主要用于匹配Uri.这里的匹配是发生在ContentProvider中的,假如我们向ContentProvider中插入一条数据,不可能为所欲为的想怎么干就怎么干,在ContentProvider肯定要做一个判断,只有在符合条件下才会去执行你想要执行的操作,这里的判断就是用UriMatch进行匹配,假如是系统的ContentProvider如联系人、图库、视频库等,这些系统都提供了Uri我们可以根据系统提供的Uri来操作相应的数据。查阅谷歌官方文档你会发现有这么几个方法

1public Uri Matcher(int code)

//它的作用就是创建一个UriMatch对象

2public void addURI(String authority,String path, int code)

//它的作用是在ContentProvider添加一个用于匹配的Uri,当匹配成功时返回codeUri可以是精确的字符串,Uri中带有*表示可匹配任意text#表示只能匹配数字。

3public int match(Uri uri)

//这里的Uri就是传过来的要进行验证,匹配的Uri假如传过来的是:content://com.example.test/student/#,content://com.example.test/student/10可以匹配成功,这里的10可以使任意的数字。

 

例如:

//UriMatcher.NO_MATCH表示不匹配任何路径的返回码

UriMatcher uriMatcher= new UriMatcher(UriMatcher.NO_MATCH);

//UriMatcher类里面添加一个拼凑的Uri

uriMatcher.addURI(“com.a.b”, "student", 100);// 匹配记录集合,100表示code

uriMatcher.addURI(“com.a.b”, "student/#", 101);// 匹配单条记录

 

三、解析者的应用

关键点1ContentResolver内容解析者

解释:当其他应用想要获取内容提供的数据时并不直接调用内容提供者对外开放的统一接口方法,而是使用一个 ContentResolver 对象,调用ContentResolver 的方法作为替代。ContentResolver可以与任意内容提供者进行会话,与其合作来对所有相关交互通讯进行管理。当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver类来完成,要获取ContentResolver对象,可以使用Context提供的getContentResolver()方法。

例如:ContentResolver contentResolver = getContentResolver();

 

ContentResolver 类也提供了与ContentProvider类相对应的四个方法:

1public Uri insert(Uri uri, ContentValues values)    

//该方法用于往ContentProvider添加数据。

 

2public int delete(Uri uri, String selection, String[] selectionArgs)   

//该方法用于从ContentProvider删除数据。

 

3public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)   

//该方法用于更新ContentProvider中的数据。

 

4public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)   

//该方法用于从ContentProvider中获取数据。

 

关键点2ContentObserver内容观察者

解释1:观察指定的Uri引起的数据库的变化,然后通知主线程,根据需求做我们想要做的处理。这样说大家可能理解的不是特别透彻,这样跟大家说它可以实现类似于AdapternotifyDataSetChanged()这个方法的作用,比方说当观察到ContentProvider的数据变化时会自动调用谷歌工程师给我们提供的好的方法,可以在此方法中通知主线程数据改变等等。那么问题来了,应该怎样实现这样的功能呢?首先要做的就是注册这个观察者,这里的注册是在需要监测ContentProvider的应用中进行注册并不是在ContentProvider中而在ContentProvider中要做的就是当数据变化时进行通知,这里的通知的方法谷歌已经帮我们写好,直接调用就行了。

这里还要注册一个观察者实例,当指定的Uri发生改变时,这个实例会回调实例对象做相应处理。通过ContentResolver(注意这个不是观察者)调用如下方法:

public final void registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer)

//参数uri:需要观察的Uri,也就是某个内容提供者定义的Uri.

//参数 notifyForDescendents:如果为true表示以这个Uri为开头的所有Uri都会被匹配到,如果为false表示精确匹配,即只会匹配这个给定的Uri

//参数 observer:内容观察者

 

解释2:内容观察者创建说明。需要创建一个类,继承ContentObserver,注意的是这里必须要实现它的构造方法

public ContentObserver(Handler handler)

这里传进去的是一个Handler对象,这个Handler对象的作用一般要依赖于ContentObserver的另一个方法即

public void onChange(boolean selfChange)

这个方法的作用就是当指定的Uri的数据发生变化时会回调该方法,此时可以借助构造方法中的Handler对象将这个变化的消息发送给主线程,当主线程接收到这个消息之后就可以按照我们的需求来完成相应的操作,比如上面提到的类似于AdapternotifyDataSetChanged()的作用。

 

关键点3CursorAdapter

解释:1CursorAdapter是继承了BaseAdapter后覆盖它的getView方法在getView方法中调用了newViewbindView方法,我们在写CursorAdapter时必须实现它的两个方法

public void bindView(View view, Context context, Cursor cursor)

public View newView(Context context, Cursor cursor, ViewGroup parent)

(1)newView:并不是每次都被调用的,它只在实例化的时候调用,数据增加的时候也会调用,但是在重绘(比如修改条目里的TextView的内容)的时候不会被调用

(2)bindView:从代码中可以看出在绘制Item之前一定会调用bindView方法它在重绘的时候也同样被调用

解释2CursorAdapter还有一个重要的方法

public void changeCursor (Cursor cursor)

该方法的功能类似于adapter.notifyDataSetChanged()方法

 

参考资料:

1、参考博客:http://blog.csdn.net/dmk877/article/details/50387741(这篇博客有源码)

2CursorAdapter详解:http://blog.csdn.net/dmk877/article/details/44983491


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值