【移動應用開發技術】還沒弄懂四大組件?帶你全面解析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

提交評論