溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

還沒(méi)弄懂四大組件?帶你全面解析ContentProvider篇

發(fā)布時(shí)間:2020-06-20 17:31:18 來(lái)源:網(wǎng)絡(luò) 閱讀:301 作者:Android解析 欄目:移動(dòng)開(kāi)發(fā)

喜歡的小伙伴歡迎關(guān)注,我會(huì)定期分享Android知識(shí)點(diǎn)及解析,還會(huì)不斷更新的BATJ面試專(zhuān)題,歡迎大家前來(lái)探討交流,如有好的文章也歡迎投稿。

1.什么是ContentProvider

ContentProvider,是自身APP開(kāi)放給第三方APP的,用于訪問(wèn)自身數(shù)據(jù)庫(kù)數(shù)據(jù)的接口。
第三方APP可以通過(guò)該接口,對(duì)指定的數(shù)據(jù)進(jìn)行增刪改查。

那么如何定義自身的ContentProvider接口呢?

在回答問(wèn)題之前,先來(lái)關(guān)注一下Uri。

2.什么是Uri

原因在于,uri是ContentProvider解析外部請(qǐng)求(或者說(shuō)是,第三方訪問(wèn)自身數(shù)據(jù)庫(kù))的關(guān)鍵參數(shù)。

Uri的字符串格式如下

content://package/table/id

例如

content://com.breakloop.sqlitehelperdemo/hero/1

從上方Uri示例中,可以獲取到以下信息。

第三方APP想要

  1. 訪問(wèn)com.breakloop.sqlitehelperdemo的數(shù)據(jù)庫(kù)。至于哪個(gè),由contentProvider內(nèi)部映射指定。

  2. 訪問(wèn)表hero。至于表名是不是真為hero,也由contentProvider說(shuō)了算。

  3. 訪問(wèn)id為1的數(shù)據(jù)。至于是不是id代表的具體含義,解釋權(quán)也歸contentProvider。

那么,第三方APP將Uri傳入后,ContentProvider如何將其map為具體的數(shù)據(jù)庫(kù)操作呢?

這便有了UriMatcher工具類(lèi)的引入。

3.UriMatcher

該工具類(lèi),可以將Uri映射為int類(lèi)型的行為代碼。行為代碼,可以看做是ContentProvider自定義的枚舉類(lèi)型。而不同的行為代碼,綁定不同的數(shù)據(jù)庫(kù)操作。

我們先來(lái)看一下,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ù)操作呢?,換句話(huà)說(shuō),在哪兒使用UriMatcher呢?當(dāng)然是ContentProvider中?。?!在ContentProvider中的增刪改查方法中,完成操作映射。

我們來(lái)看一下,ContentProvider的創(chuàng)建。

4.ContentProvider的創(chuàng)建

先用Android Studio 創(chuàng)建一個(gè)ContentProvider.

還沒(méi)弄懂四大組件?帶你全面解析ContentProvider篇


創(chuàng)建過(guò)程中,需要提供AUTHORITY,

還沒(méi)弄懂四大組件?帶你全面解析ContentProvider篇


ContentProvider生成后,Android Studio將自動(dòng)幫助ContentProvider在Manifest中進(jìn)行注冊(cè)。

還沒(méi)弄懂四大組件?帶你全面解析ContentProvider篇

接下來(lái),我們看看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?android.net.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)造方法,沒(méi)什么可解釋的。

關(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;
????}

再來(lái)看一下稍微復(fù)雜的查詢(xún)。

????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,在必要的位置使用方法

public ContentResolver getContentResolver()

獲取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

既然,寫(xiě)入成功,那我們查詢(xún)一下。

????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è)賮?lái)更新一下。

????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.MainActivity:?name?=?D?age?=?13?Female
I/com.breakloop.contentproviderdemo2.MainActivity:?Delete?by?Sex
I/com.breakloop.contentproviderdemo2.MainActivity:?delete?2?record
I/com.breakloop.contentproviderdemo2.MainActivity:?Select?All
I/com.breakloop.contentproviderdemo2.MainActivity:?Delete?All
I/com.breakloop.contentproviderdemo2.MainActivity:?delete?0?record
I/com.breakloop.contentproviderdemo2.MainActivity:?Select?All

至此,ContentProvider的創(chuàng)建和使用便介紹完了。

如果,只是為了使用,可以只看到這里就好了!


之后的部分,本文還未找到答案!因此,只是記錄!
如果有知道的朋友,還望指點(diǎn)。

那么,還有什么?

還記得ContentProvider中的getType嗎?
到目前為止,我們并沒(méi)有實(shí)現(xiàn)getType方法。而這并沒(méi)有對(duì)ContentProvider的使用造成任何影響。那么問(wèn)題來(lái)了。getType干嘛用的?什么時(shí)候用?

對(duì)于getType的解釋?zhuān)W(wǎng)上有兩種。

1. 用于對(duì)返回?cái)?shù)據(jù)的解析。判斷是一條數(shù)據(jù),還是多條數(shù)據(jù)。若getType方法被實(shí)現(xiàn),則按照實(shí)現(xiàn)方法解析,提高了工作效率。否則,系統(tǒng)自動(dòng)解析。
2. 避免new Intent(String action, Uri uri)方式無(wú)法啟動(dòng)activity。
對(duì)于解釋1,并未從找到官方的出處。而對(duì)于解釋2,不太明白!我用ContentProvideractivity何事?

關(guān)于getType方法的實(shí)現(xiàn),其原型注釋給出了答案。

還沒(méi)弄懂四大組件?帶你全面解析ContentProvider篇


方法返回的是MIME類(lèi)型的String形式。根據(jù)Uri的結(jié)尾不同,輸出也不同。
若Uri以Path結(jié)尾,則返回格式為

vnd.android.cursor.dir/vnd.<authority>.<path>

若Uri以id結(jié)尾,則返回格式為

vnd.android.cursor.item/vnd.<authority>.<path>

因此,我們實(shí)例中的getType()實(shí)現(xiàn)為

????@Override
????public?String?getType(Uri?uri)?{
????????Log.i(TAG,?"getType:?");????????String?authorityAndPath=MatcherConst.AUTHORITY+"."+DBConst.TABLE_PERSON;????????String?handerPath="vnd.android.cursor.dir/vnd.";????????String?handerID="vnd.android.cursor.item/vnd.";????????switch?(matcher.match(uri)){????????????case?MatcherConst.BY_NONE:????????????????return?handerPath+authorityAndPath;????????????case?MatcherConst.BY_AGE:????????????case?MatcherConst.BY_SEX:????????????case?MatcherConst.BY_NAME:????????????????return?handerID+authorityAndPath;????????????default:????????????????return?null;
????????}
????}

8.總結(jié)

  • 本文主要介紹了Android中四大組件的ContentProvider的一些知識(shí),覺(jué)得文章不錯(cuò)的喜歡的小伙伴可以關(guān)注加分享,也歡迎大家前來(lái)探討交流。


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI