【移动应用开发技术】还没弄懂四大组件?带你全面解析ContentProvider篇_第1页
【移动应用开发技术】还没弄懂四大组件?带你全面解析ContentProvider篇_第2页
【移动应用开发技术】还没弄懂四大组件?带你全面解析ContentProvider篇_第3页
【移动应用开发技术】还没弄懂四大组件?带你全面解析ContentProvider篇_第4页
【移动应用开发技术】还没弄懂四大组件?带你全面解析ContentProvider篇_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】还没弄懂四大组件?带你全面解析ContentProvider篇

喜欢的小伙伴欢迎关注,我会定期分享Android知识点及解析,还会不断更新的BATJ面试专题,欢迎大家前来探讨交流,如有好的文章也欢迎投稿。1.什么是ContentProviderContentProvider,是自身APP开放给第三方APP的,用于访问自身数据库数据的接口。第三方APP可以通过该接口,对指定的数据进行增删改查。那么如何定义自身的ContentProvider接口呢?在回答问题之前,先来关注一下Uri。2.什么是Uri原因在于,uri是ContentProvider解析外部请求(或者说是,第三方访问自身数据库)的关键参数。Uri的字符串格式如下content://package/table/idcontent://package/table/id例如content://com.breakloop.sqlitehelperdemo/hero/1content://com.breakloop.sqlitehelperdemo/hero/1从上方Uri示例中,可以获取到以下信息。第三方APP想要访问com.breakloop.sqlitehelperdemo的数据库。至于哪个,由contentProvider内部映射指定。访问表hero。至于表名是不是真为hero,也由contentProvider说了算。访问id为1的数据。至于是不是id代表的具体含义,解释权也归contentProvider。那么,第三方APP将Uri传入后,ContentProvider如何将其map为具体的数据库操作呢?这便有了UriMatcher工具类的引入。3.UriMatcher该工具类,可以将Uri映射为int类型的行为代码。行为代码,可以看做是ContentProvider自定义的枚举类型。而不同的行为代码,绑定不同的数据库操作。我们先来看一下,Uri与行为代码的映射关系

public

final

static

String

AUTHORITY="com.breakloop.contentproviderdemo1";

public

final

static

int

BY_NAME=1;

public

final

static

int

BY_AGE=2;

public

final

static

int

BY_SEX=3;

public

final

static

int

BY_NONE=0;

public

final

static

String

PATH_BY_NAME=DBConst.TABLE_PERSON+"/ByName/*";

public

final

static

String

PATH_BY_AGE=DBConst.TABLE_PERSON+"/ByAge/#";

public

final

static

String

PATH_BY_SEX=DBConst.TABLE_PERSON+"/BySex/*";

}static

{

matcher=new

UriMatcher(UriMatcher.NO_MATCH);

matcher.addURI(MatcherConst.AUTHORITY,MatcherConst.PATH_BY_NAME,MatcherConst.BY_NAME);

matcher.addURI(MatcherConst.AUTHORITY,MatcherConst.PATH_BY_AGE,MatcherConst.BY_AGE);

matcher.addURI(MatcherConst.AUTHORITY,MatcherConst.PATH_BY_SEX,MatcherConst.BY_SEX);

matcher.addURI(MatcherConst.AUTHORITY,DBConst.TABLE_PERSON,MatcherConst.BY_NONE);

}在上面的示例中,UriMatch绑定了四个Uri,并将各个Uri映射为四个行为代码。其中,用到了转义符。#代表任意数字,*代表任意字母。那么如何将行为代码映射为具体的数据库操作呢?,换句话说,在哪儿使用UriMatcher呢?当然是ContentProvider中!!!在ContentProvider中的增删改查方法中,完成操作映射。我们来看一下,ContentProvider的创建。4.ContentProvider的创建先用AndroidStudio创建一个ContentProvider.创建过程中,需要提供AUTHORITY,ContentProvider生成后,AndroidStudio将自动帮助ContentProvider在Manifest中进行注册。接下来,我们看看ContentProvider的结构。5.ContentProvider的结构import

android.content.ContentProvider;import

android.content.ContentValues;import

android.content.UriMatcher;import

android.database.Cursor;import

.Uri;public

class

MyContentProvider

extends

ContentProvider

{

public

MyContentProvider()

{

}

@Override

public

int

delete(Uri

uri,

String

selection,

String[]

selectionArgs)

{

//

Implement

this

to

handle

requests

to

delete

one

or

more

rows.

throw

new

UnsupportedOperationException("Not

yet

implemented");

}

@Override

public

String

getType(Uri

uri)

{

//

TODO:

Implement

this

to

handle

requests

for

the

MIME

type

of

the

data

//

at

the

given

URI.

throw

new

UnsupportedOperationException("Not

yet

implemented");

}

@Override

public

Uri

insert(Uri

uri,

ContentValues

values)

{

//

TODO:

Implement

this

to

handle

requests

to

insert

a

new

row.

throw

new

UnsupportedOperationException("Not

yet

implemented");

}

@Override

public

boolean

onCreate()

{

//

TODO:

Implement

this

to

initialize

your

content

provider

on

startup.

return

false;

}

@Override

public

Cursor

query(Uri

uri,

String[]

projection,

String

selection,

String[]

selectionArgs,

String

sortOrder)

{

//

TODO:

Implement

this

to

handle

query

requests

from

clients.

throw

new

UnsupportedOperationException("Not

yet

implemented");

}

@Override

public

int

update(Uri

uri,

ContentValues

values,

String

selection,

String[]

selectionArgs)

{

//

TODO:

Implement

this

to

handle

requests

to

update

one

or

more

rows.

throw

new

UnsupportedOperationException("Not

yet

implemented");

}

}一共七个方法。包括一个构造方法,四个数据库方法(增删改查),一个初始化方法(onCreate),还有一个getType。关于getType,我们之后解释。关于构造方法,没什么可解释的。关于初始化方法,当返回true时,表明初始化成功,否则,失败。由于我们要对数据库进行操作,因此,需要获取sqlite数据库对象。public

boolean

onCreate()

{

helper=new

mySqliteHelper(getContext(),DBConst.DB_NAME,null,1);

return

true;

}关于数据库方法,我们看到传参中存在Uri,因此,这里需要用到UirMatcher了。我们将刚才的UriMatcher代码段,加入MyContentProvider.这样,我们就可以在各个数据库方法中,解析Uri了。同时,由于sqlite数据库对象的存在,进而可以对数据库进行相应操作。6.行为代码Mapping数据库操作我们先看一下最简单的插入操作。

public

Uri

insert(Uri

uri,

ContentValues

values)

{

Uri

returnUri=null;

SQLiteDatabase

db=helper.getWritableDatabase();

switch

(matcher.match(uri)){

case

MatcherConst.BY_NONE:

long

recordID=db.insert(DBConst.TABLE_PERSON,null,values);

returnUri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/"+recordID);

break;

default:

break;

}

return

returnUri;

}再来看一下稍微复杂的查询。

public

Cursor

query(Uri

uri,

String[]

projection,

String

selection,

String[]

selectionArgs,

String

sortOrder)

{

Cursor

cursor=null;

SQLiteDatabase

db=helper.getReadableDatabase();

switch

(matcher.match(uri)){

case

MatcherConst.BY_NONE:

cursor=db.query(DBConst.TABLE_PERSON,projection,selection,selectionArgs,null,null,sortOrder);

break;

case

MatcherConst.BY_AGE:

cursor=db.query(DBConst.TABLE_PERSON,projection,DBConst.COLUMN_AGE+"=?",new

String[]{uri.getPathSegments().get(2)},null,null,sortOrder);

break;

case

MatcherConst.BY_SEX:

cursor=db.query(DBConst.TABLE_PERSON,projection,DBConst.COLUMN_SEX+"=?",new

String[]{uri.getPathSegments().get(2)},null,null,sortOrder);

break;

case

MatcherConst.BY_NAME:

cursor=db.query(DBConst.TABLE_PERSON,projection,DBConst.COLUMN_NAME+"=?",new

String[]{uri.getPathSegments().get(2)},null,null,sortOrder);

break;

default:

break;

}

return

cursor;

}这里需要注意的是,如何取Uri中的传入数据。使用的获取方法是uri.getPathSegments().get(index)。该方法获取的是AUTHORITY后面的String部分。然后,以”/”为分隔符,生成String[]。接着是更新操作。

@Override

public

int

update(Uri

uri,

ContentValues

values,

String

selection,

String[]

selectionArgs)

{

int

recordID=0;

SQLiteDatabase

db=helper.getWritableDatabase();

switch

(matcher.match(uri)){

case

MatcherConst.BY_NONE:

recordID=db.update(DBConst.TABLE_PERSON,values,null,null);

break;

case

MatcherConst.BY_AGE:

recordID=db.update(DBConst.TABLE_PERSON,values,DBConst.COLUMN_AGE+"=?",new

String[]{uri.getPathSegments().get(2)});

break;

case

MatcherConst.BY_SEX:

recordID=db.update(DBConst.TABLE_PERSON,values,DBConst.COLUMN_SEX+"=?",new

String[]{uri.getPathSegments().get(2)});

break;

case

MatcherConst.BY_NAME:

recordID=db.update(DBConst.TABLE_PERSON,values,DBConst.COLUMN_NAME+"=?",new

String[]{uri.getPathSegments().get(2)});

break;

default:

break;

}

return

recordID;

}还有删除。

public

int

delete(Uri

uri,

String

selection,

String[]

selectionArgs)

{

int

recordID=0;

SQLiteDatabase

db=helper.getWritableDatabase();

switch

(matcher.match(uri)){

case

MatcherConst.BY_NONE:

recordID=db.delete(DBConst.TABLE_PERSON,null,null);

break;

case

MatcherConst.BY_AGE:

recordID=db.delete(DBConst.TABLE_PERSON,DBConst.COLUMN_AGE+"=?",new

String[]{uri.getPathSegments().get(2)});

break;

case

MatcherConst.BY_SEX:

recordID=db.delete(DBConst.TABLE_PERSON,DBConst.COLUMN_SEX+"=?",new

String[]{uri.getPathSegments().get(2)});

break;

case

MatcherConst.BY_NAME:

recordID=db.delete(DBConst.TABLE_PERSON,DBConst.COLUMN_NAME+"=?",new

String[]{uri.getPathSegments().get(2)});

break;

default:

break;

}

return

recordID;

}那么,第三方如何调用ContentProvider呢?7.ContentProvider的使用这里,我们新建一个工程contentproviderdemo2,在必要的位置使用方法publicContentResolvergetContentResolver()publicContentResolvergetContentResolver()获取ContentProvider实例,之后便可传入Uri,调用数据库相关方法了。例如,我们插入四条记录。

Uri

returnUri=null;

ContentResolver

resolver=getContentResolver();

Uri

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

ContentValues

values=new

ContentValues();

values.put(DBConst.COLUMN_NAME,"A");

values.put(DBConst.COLUMN_AGE,10);

values.put(DBConst.COLUMN_SEX,"Male");

returnUri=resolver.insert(uri,values);

if(returnUri!=null)

Log.i(TAG,

"return

Uri

=

"+returnUri.toString());

values.put(DBConst.COLUMN_NAME,"B");

values.put(DBConst.COLUMN_AGE,11);

values.put(DBConst.COLUMN_SEX,"Male");

returnUri=resolver.insert(uri,values);

if(returnUri!=null)

Log.i(TAG,

"return

Uri

=

"+returnUri.toString());

values.put(DBConst.COLUMN_NAME,"C");

values.put(DBConst.COLUMN_AGE,12);

values.put(DBConst.COLUMN_SEX,"Female");

returnUri=resolver.insert(uri,values);

if(returnUri!=null)

Log.i(TAG,

"return

Uri

=

"+returnUri.toString());

values.put(DBConst.COLUMN_NAME,"D");

values.put(DBConst.COLUMN_AGE,13);

values.put(DBConst.COLUMN_SEX,"Female");

returnUri=resolver.insert(uri,values);

if(returnUri!=null)

Log.i(TAG,

"return

Uri

=

"+returnUri.toString());我们看一下输出结果。I/com.breakloop.contentproviderdemo2.MainActivity:

return

Uri

=

content://com.breakloop.contentproviderdemo1/PERSON/1I/com.breakloop.contentproviderdemo2.MainActivity:

return

Uri

=

content://com.breakloop.contentproviderdemo1/PERSON/2I/com.breakloop.contentproviderdemo2.MainActivity:

return

Uri

=

content://com.breakloop.contentproviderdemo1/PERSON/3I/com.breakloop.contentproviderdemo2.MainActivity:

return

Uri

=

content://com.breakloop.contentproviderdemo1/PERSON/4既然,写入成功,那我们查询一下。

public

void

selectRecord(){

Uri

uri;

String

name="A";

int

age=11;

String

sex="Male";

Log.i(TAG,

"Select

by

Name");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/ByName/"+name);

selectRecord(uri);

Log.i(TAG,

"Select

by

Age");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/ByAge/"+age);

selectRecord(uri);

Log.i(TAG,

"Select

by

Sex");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/BySex/"+sex);

selectRecord(uri);

Log.i(TAG,

"Select

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

selectRecord(uri);

}

private

void

selectRecord(Uri

uri){

Cursor

cursor;

cursor=resolver.query(uri,new

String[]{DBConst.COLUMN_AGE,

DBConst.COLUMN_NAME,

DBConst.COLUMN_SEX},null,null,null);

if(cursor!=null){

while(cursor.moveToNext()){

Log.i(TAG,

"name

=

"+cursor.getString(1)+

"

age

=

"+cursor.getInt(0)

+"

"+cursor.getString(2));

}

}

}输出结果如下I/com.breakloop.contentproviderdemo2.MainActivity:

Select

by

Name

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

A

age

=

10

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

Select

by

Age

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

B

age

=

11

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

Select

by

Sex

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

A

age

=

10

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

B

age

=

11

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

Select

All

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

A

age

=

10

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

B

age

=

11

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

C

age

=

12

Female

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

D

age

=

13

Female我们再来更新一下。

public

void

updateRecord(){

Uri

uri;

String

name="A";

int

age=11;

String

sex="Female";

ContentValues

values=new

ContentValues();

Log.i(TAG,

"Update

by

Name");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/ByName/"+name);

values.put(DBConst.COLUMN_NAME,name+name);

update(uri,values);

Log.i(TAG,

"Update

by

Age");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/ByAge/"+age);

values.clear();

values.put(DBConst.COLUMN_AGE,14);

update(uri,values);

Log.i(TAG,

"Update

by

Sex");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/BySex/"+sex);

values.clear();

values.put(DBConst.COLUMN_AGE,15);

update(uri,values);

Log.i(TAG,

"Update

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

values.put(DBConst.COLUMN_SEX,"Male");

update(uri,values);

Log.i(TAG,

"Select

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

selectRecord(uri);

}

private

void

update(Uri

uri,ContentValues

values){

int

count;

count=resolver.update(uri,values,null,null);

Log.i(TAG,

"update

"+count+"

record");

}结果如下I/com.breakloop.contentproviderdemo2.MainActivity:

Update

by

Name

I/com.breakloop.contentproviderdemo2.MainActivity:

update

1

record

I/com.breakloop.contentproviderdemo2.MainActivity:

Update

by

Age

I/com.breakloop.contentproviderdemo2.MainActivity:

update

1

record

I/com.breakloop.contentproviderdemo2.MainActivity:

Update

by

Sex

I/com.breakloop.contentproviderdemo2.MainActivity:

update

2

record

I/com.breakloop.contentproviderdemo2.MainActivity:

Update

All

I/com.breakloop.contentproviderdemo2.MainActivity:

update

4

record

I/com.breakloop.contentproviderdemo2.MainActivity:

Select

All

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

AA

age

=

15

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

B

age

=

15

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

C

age

=

15

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

D

age

=

15

Male都不要了,删除!(这里是对更新前的数据库进行的操作)

public

void

deleteRecord(){

Uri

uri;

String

name="A";

int

age=11;

String

sex="Female";

Log.i(TAG,

"Delete

by

Name");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/ByName/"+name);

delete(uri);

Log.i(TAG,

"Select

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

selectRecord(uri);

Log.i(TAG,

"Delete

by

Age");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/ByAge/"+age);

delete(uri);

Log.i(TAG,

"Select

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

selectRecord(uri);

Log.i(TAG,

"Delete

by

Sex");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON+"/BySex/"+sex);

delete(uri);

Log.i(TAG,

"Select

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

selectRecord(uri);

Log.i(TAG,

"Delete

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

delete(uri);

Log.i(TAG,

"Select

All");

uri=Uri.parse("content://"+MatcherConst.AUTHORITY+"/"+DBConst.TABLE_PERSON);

selectRecord(uri);

}

private

void

delete(Uri

uri){

int

count;

count=resolver.delete(uri,null,null);

Log.i(TAG,

"delete

"+count+"

record");

}结果如下I/com.breakloop.contentproviderdemo2.MainActivity:

delete

1

record

I/com.breakloop.contentproviderdemo2.MainActivity:

Select

All

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

B

age

=

11

Male

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

C

age

=

12

Female

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

D

age

=

13

Female

I/com.breakloop.contentproviderdemo2.MainActivity:

Delete

by

Age

I/com.breakloop.contentproviderdemo2.MainActivity:

delete

1

record

I/com.breakloop.contentproviderdemo2.MainActivity:

Select

All

I/com.breakloop.contentproviderdemo2.MainActivity:

name

=

C

age

=

12

Female

I/com.breakloop.contentproviderdemo2.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论