【个人】Content Provider个人见解

来源:互联网 发布:沙特投资歼31知乎 编辑:程序博客网 时间:2024/06/05 20:34


一、Content Provider数据共享


第一步,

     ContentProvider 在android中的作用是对外共享数据, 也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对你应用中的数据 进行添删改查。关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE或 Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。那么,这里为何要使用ContentProvider对外共享数据 呢?是这样的,如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式而不同,导致数据的访问方式无法统一,如:采用xml文件对外共享数 据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据。

使用ContentProvider对外共享数据的好处是统一了数据的访问方式。

使用Content Provider的第一步,需要继承Content Provider,并重写其中的方法。

第二步,

     要在AndroidMainfest中进行配置,为了让其他应用程序找到Content Provider。我们需要给Content Provider配置一个唯一的标识,即authorities属性,它好比是一个网站,authorities就是它的域名。

android:authorities="com.ljq.providers.personprovider"/>

二、URI解释


其中,scheme已经被Android所规定,只能为content://。                                                                                   
主机名(authority):是我们将要使用或者的Content Provider,外部应用如果要使用它,则它是唯一的标识。
路径(Path):是我们将要操作的数据。比如:

操作person表中id为10的数据:person/10
操作person表中id为10的name字段:person/10/name
操作person表中所有的数据:person

我们也可以操作不为数据库的数据,例如,想要操作xml里面person节点下的name节点:person/name

注意:要将字符串转化为uri类型,需要使用到URI.parse()方法,即

Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person")

三、UriMatcher 类使用介绍

前面我们已经介绍到,Uri是我们要操作的数据。所以,我们要解析Uri数据。因此,android为我们提供了2类解析Uri的类。UriMatcher 和 ContentUris

UriMather用于匹配Uri,具体使用如下:
第一步,将要需要使用的Uri路径全部匹配上去,

//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMathcer mather = new UrlMathcer(UriMathcer.NO_MATCH);

//如果match()方法匹配content://com.ljq.provider.personprovider/person路径,返回匹配码为1
matcher.addURI("com.ljq.provider.personprovider", "person", 1);//添加需要匹配的uri,如果匹配则返回匹配码

//如果match()方法匹配content://com.ljq.provider.personprovider/person/201路径,返回匹配码为2
matcher.addURI("com.ljq.provider.personprovider", "person/#", 2);//因为#是通配符,所以,不管是ID为几,它都表示为匹配

使用方法:

switch(matcher.match(uri)){  case 1:{    break;}  case 2:{    break;}}

注册完成后,就可以使用mather.match(uri)方法对输入的Uri数据进行匹配,如果匹配,则返回匹配码。匹配码是调用match.addUri()方法进行传入的第3个参数。

四、ContentUris使用

ContentUris用于操作Uri后面的ID部分,它有2个比较使用的方法:

withAppendedId(uri,id):给uri地址上面加上ID
Uri uri = Uri.parse("content://com.wangpei.provider.personprovider/person");Uri resultUri = ContentUris.withAppendedId(uri,10);

生成的uri为:content://com.wangpei.provider.personprovider/person/10

parseId(uri):用于从uri中获取Id部分
Uri uri = Uri.parse("content://com.wangpei.provider.personprovider/person/10");long id = ContentUris.parseId(uri);//结果为10

id的值为10

五、使用Content Provider共享数据


Content Provier主要的方法有:

public boolean onCreate()                                                                            
该方法是在Content Provider创建后就会被调用。android开机后,只有应用程序访问Content Provider里面的数据时,才会被创建。

public Uri insert(Uri uri, ContentValues values)                                                     
该方法是供外部程序往Content Provider里面插入新的数据。

public int delete(Uri uri, String selection, String[] selectionArgs)                                 
该方法是供外部程序在Content Provider里面删除符合条件的数据。

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)            
该方法是供外部程序更新Content Provide里面的符合条件的数据。

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法是供外部程序获得Content Provider里面符合条件的数据。

public String getType(Uri uri)                                                                       
该方法用于返回当前Uri所代表的数据的MIME类型,有以下2中情况:

1.如果操作的数据类型属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:
要得到数据为person的所有记录Uri:content://com.wangpei.provider.persionprovider/person,那么返回的MIME类型字符串为:“vnd.android.cursor.dir/person”

2.如果操作的书库类型属于非集合类型,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:
要得到的数据为person中id为10的记录Uri:content://com.wangpei.provider.personprovider/person/10,把么返回的MIME类型字符串为:“vnd.android.cursor.item/person”


六、使用ContentResolver操作Content Provider里面的数据     


当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver类来完成,获取ContentResolver对象,可以使用Activity提供的getContentResolver()方法。

ContentResolver类提供了和ContentProvider类相同的四个方法:

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

public Uri insert(Uri uri,ContentValues values);

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

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

这些方法的第一个参数为uri,它表示对什么数据进行操作。下面我们会举一些例子:


ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person");//添加一条记录ContentValues values = new ContentValues();values.put("name", "linjiqin");values.put("age", 25);resolver.insert(uri, values); //获取person表中所有记录Cursor cursor = resolver.query(uri, null, null, null, "personid desc");while(cursor.moveToNext()){Log.i("ContentTest", "personid="+ cursor.getInt(0)+ ",name="+ cursor.getString(1));}//把id为1的记录的name字段值更改新为zhangsanContentValues updateValues = new ContentValues();updateValues.put("name", "zhangsan");Uri updateIdUri = ContentUris.withAppendedId(uri, 2);resolver.update(updateIdUri, updateValues, null, null);//删除id为2的记录Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);resolver.delete(deleteIdUri, null, null);
                                                                                                                    

七、监听Content Provider中数据的变化

如果Content Provider的访问者需要知道Content Provider中数据发生变化,可以在ContentProvider发生数据变化时调用:
getContentResolver。notifyChange(uri,null);//通知注册在此Uri上的访问者

例子:
public class PersonContentProvider extends ContentProvider {public Uri insert(Uri uri, ContentValues values) {db.insert("person", "personid", values);getContext().getContentResolver().notifyChange(uri, null);//数据发生变化,进行通知}}

如果Content Provider的访问者需要得到数据变化的通知,必须使用ContentObserver进行监听,当监听到数据发生变化时,则系统会调用ContentObserver的onChange()方法:
getContentResolver().registerContentObserver(Uri.parse("content://com.ljq.providers.personprovider/person"),true, new PersonObserver(new Handler()));public class PersonObserver extends ContentObserver{public PersonObserver(Handler handler) {super(handler);}public void onChange(boolean selfChange) {//此处可以进行相应的业务处理}}







0 0
原创粉丝点击