【移動(dòng)應(yīng)用開發(fā)技術(shù)】還沒弄懂四大組件?帶你全面解析ContentProvider篇_第1頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】還沒弄懂四大組件?帶你全面解析ContentProvider篇_第2頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】還沒弄懂四大組件?帶你全面解析ContentProvider篇_第3頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】還沒弄懂四大組件?帶你全面解析ContentProvider篇_第4頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】還沒弄懂四大組件?帶你全面解析ContentProvider篇_第5頁(yè)
已閱讀5頁(yè),還剩10頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開發(fā)技術(shù)】還沒弄懂四大組件?帶你全面解析ContentProvider篇

喜歡的小伙伴歡迎關(guān)注,我會(huì)定期分享Android知識(shí)點(diǎn)及解析,還會(huì)不斷更新的BATJ面試專題,歡迎大家前來探討交流,如有好的文章也歡迎投稿。1.什么是ContentProviderContentProvider,是自身APP開放給第三方APP的,用于訪問自身數(shù)據(jù)庫(kù)數(shù)據(jù)的接口。第三方APP可以通過該接口,對(duì)指定的數(shù)據(jù)進(jìn)行增刪改查。那么如何定義自身的ContentProvider接口呢?在回答問題之前,先來關(guān)注一下Uri。2.什么是Uri原因在于,uri是ContentProvider解析外部請(qǐng)求(或者說是,第三方訪問自身數(shù)據(jù)庫(kù))的關(guān)鍵參數(shù)。Uri的字符串格式如下content://package/table/idcontent://package/table/id例如content://com.breakloop.sqlitehelperdemo/hero/1content://com.breakloop.sqlitehelperdemo/hero/1從上方Uri示例中,可以獲取到以下信息。第三方APP想要訪問com.breakloop.sqlitehelperdemo的數(shù)據(jù)庫(kù)。至于哪個(gè),由contentProvider內(nèi)部映射指定。訪問表hero。至于表名是不是真為hero,也由contentProvider說了算。訪問id為1的數(shù)據(jù)。至于是不是id代表的具體含義,解釋權(quán)也歸contentProvider。那么,第三方APP將Uri傳入后,ContentProvider如何將其map為具體的數(shù)據(jù)庫(kù)操作呢?這便有了UriMatcher工具類的引入。3.UriMatcher該工具類,可以將Uri映射為int類型的行為代碼。行為代碼,可以看做是ContentProvider自定義的枚舉類型。而不同的行為代碼,綁定不同的數(shù)據(jù)庫(kù)操作。我們先來看一下,Uri與行為代碼的映射關(guān)系

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綁定了四個(gè)Uri,并將各個(gè)Uri映射為四個(gè)行為代碼。其中,用到了轉(zhuǎn)義符。#代表任意數(shù)字,*代表任意字母。那么如何將行為代碼映射為具體的數(shù)據(jù)庫(kù)操作呢?,換句話說,在哪兒使用UriMatcher呢?當(dāng)然是ContentProvider中?。?!在ContentProvider中的增刪改查方法中,完成操作映射。我們來看一下,ContentProvider的創(chuàng)建。4.ContentProvider的創(chuàng)建先用AndroidStudio創(chuàng)建一個(gè)ContentProvider.創(chuàng)建過程中,需要提供AUTHORITY,ContentProvider生成后,AndroidStudio將自動(dòng)幫助ContentProvider在Manifest中進(jìn)行注冊(cè)。接下來,我們看看ContentProvider的結(jié)構(gòu)。5.ContentProvider的結(jié)構(gòu)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");

}

}一共七個(gè)方法。包括一個(gè)構(gòu)造方法,四個(gè)數(shù)據(jù)庫(kù)方法(增刪改查),一個(gè)初始化方法(onCreate),還有一個(gè)getType。關(guān)于getType,我們之后解釋。關(guān)于構(gòu)造方法,沒什么可解釋的。關(guān)于初始化方法,當(dāng)返回true時(shí),表明初始化成功,否則,失敗。由于我們要對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,因此,需要獲取sqlite數(shù)據(jù)庫(kù)對(duì)象。public

boolean

onCreate()

{

helper=new

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

return

true;

}關(guān)于數(shù)據(jù)庫(kù)方法,我們看到傳參中存在Uri,因此,這里需要用到UirMatcher了。我們將剛才的UriMatcher代碼段,加入MyContentProvider.這樣,我們就可以在各個(gè)數(shù)據(jù)庫(kù)方法中,解析Uri了。同時(shí),由于sqlite數(shù)據(jù)庫(kù)對(duì)象的存在,進(jìn)而可以對(duì)數(shù)據(jù)庫(kù)進(jìn)行相應(yīng)操作。6.行為代碼Mapping數(shù)據(jù)庫(kù)操作我們先看一下最簡(jiǎn)單的插入操作。

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;

}再來看一下稍微復(fù)雜的查詢。

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中的傳入數(shù)據(jù)。使用的獲取方法是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;

}那么,第三方如何調(diào)用ContentProvider呢?7.ContentProvider的使用這里,我們新建一個(gè)工程contentproviderdemo2,在必要的位置使用方法publicContentResolvergetContentResolver()publicContentResolvergetContentResolver()獲取ContentProvider實(shí)例,之后便可傳入U(xiǎn)ri,調(diào)用數(shù)據(jù)庫(kù)相關(guān)方法了。例如,我們插入四條記錄。

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());我們看一下輸出結(jié)果。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));

}

}

}輸出結(jié)果如下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我們?cè)賮砀乱幌隆?/p>

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");

}結(jié)果如下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都不要了,刪除?。ㄟ@里是對(duì)更新前的數(shù)據(jù)庫(kù)進(jìn)行的操作)

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");

}結(jié)果如下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等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論