android contentProvider

除了共享內(nèi)存(SDCard)的數(shù)據(jù)外砚殿,其他包括SQLite似炎、SharedPreferences都是僅限于被當(dāng)前所創(chuàng)建的應(yīng)用訪問,而無法使它們的數(shù)據(jù)在應(yīng)用程序之間交換數(shù)據(jù)叹阔,所以Android提供了ContentProvider传睹,ContentProvider具有以下特點(diǎn):

  • 應(yīng)用程序間共享數(shù)據(jù)的一種方式
  • 為存儲(chǔ)和獲取數(shù)據(jù)提供統(tǒng)一接口
  • android為一些常見的數(shù)據(jù)提供了ContentProvider:
    • Browser:存儲(chǔ)如瀏覽器的信息欧啤。
    • CallLog:存儲(chǔ)通話記錄等信息。
    • Contacts:存儲(chǔ)聯(lián)系人等信息店印。
    • MediaStore:存儲(chǔ)媒體文件的信息倒慧。
    • Settings:存儲(chǔ)設(shè)備的設(shè)置和首選項(xiàng)信息。
ContentProvider可以理解為一個(gè)Android應(yīng)用對(duì)外開放的接口, 只要是符合它所定義的Uri格式的請(qǐng)求付秕,均可以正常訪問執(zhí)行操作。
訪問ContentProvider

ContentProvider 實(shí)例通過處理來自其他應(yīng)用的請(qǐng)求來管理對(duì)結(jié)構(gòu)化數(shù)據(jù)集的訪問掠河。所有形式的訪問最終都會(huì)調(diào)用 ContentResolver唠摹,后者接著調(diào)用ContentProvider的具體方法來獲取訪問權(quán)限奉瘤。

一般使用Context.getContentResolver()方法獲取ContentResolver對(duì)象。

ContentResolver 可提供insert望艺、query肌访、update吼驶、delete等方法.

例如,要從用戶字典提供程序中獲取字詞及其區(qū)域設(shè)置的列表风钻,則需調(diào)用 ContentResolver.query()酒请。

// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
    UserDictionary.Words.CONTENT_URI,   
    mProjection,                        
    mSelectionClause                  
    mSelectionArgs,                     
    mSortOrder);                        
query() 參數(shù) SELECT 關(guān)鍵字/參數(shù) 備注
Uri FROM table_name Uri 映射至名為 table_name 的提供程序中的表羞反。
projection col,col,col,... projection 是應(yīng)該為檢索到的每個(gè)行包含的列的數(shù)組。
selection WHERE col = value selection 會(huì)指定選擇行的條件是趴。
selectionArgs (沒有完全等效項(xiàng)澄惊。選擇參數(shù)會(huì)替換選擇子句中 ? 的占位符掸驱。)
sortOrder ORDER BY col,col,... sortOrder 指定行在返回的 Cursor 中的顯示順序。
內(nèi)容 URI

在Android中滚婉,Uri是一種比較常見的資源訪問方式帅刀。每一個(gè)ContentProvider都擁有一個(gè)公共的URI,這個(gè)URI用于表示這個(gè)ContentProvider所提供的數(shù)據(jù)骇窍。

<srandard_prefix>://<authority>/<data_path>/<id>

  • <srandard_prefix>:
    ContentProvider的標(biāo)準(zhǔn)前綴始終是content://腹纳。
  • <authority>:URI 的標(biāo)識(shí)驱犹,用于唯一標(biāo)識(shí)這個(gè)ContentProvider,外部調(diào)用者可以根據(jù)這個(gè)標(biāo)識(shí)來找到它佃牛。它定義了是哪個(gè)Content Provider提供這些數(shù)據(jù)医舆。對(duì)于第三方應(yīng)用程序,為了保證URI標(biāo)識(shí)的唯一性爷速,它必須是一個(gè)完整的惫东、小寫的類名。一般為該ContentProvider的包.類的名稱
  • <data_path>:請(qǐng)求的數(shù)據(jù)類型, 如數(shù)據(jù)庫的表禁谦。
  • <id>:指定請(qǐng)求的特定數(shù)據(jù)废封。如果URI中包含表示需要獲取的記錄的ID漂洋;則就返回該id對(duì)應(yīng)的數(shù)據(jù),如果沒有ID刽漂,就表示返回全部
content://user_dictionary/words
content://com.example.app.provider/table3/1
//對(duì)應(yīng)由 表table3中1標(biāo)識(shí)的行的內(nèi)容 URI贝咙。
content://com.example.app.provider/table3/1/name
//對(duì)應(yīng)由 表table3中1標(biāo)識(shí)的行的name字段內(nèi)容 URI。
UriMatcher

UriMatcher會(huì)將內(nèi)容 URI“模式”映射到整型值窟她。 可以在一個(gè) switch 語句中使用這些整型值震糖,為匹配特定模式的一個(gè)或多個(gè)內(nèi)容 URI 執(zhí)行相應(yīng)操作趴腋。

內(nèi)容 URI 模式使用通配符匹配內(nèi)容 URI:

*:匹配由任意長度的任何有效字符組成的字符串
#:匹配由任意長度的數(shù)字字符組成的字符串

假設(shè)一個(gè)具有權(quán)限 com.example.app.provider的提供程序能識(shí)別以下指向表的內(nèi)容 URI:

content://com.example.app.provider/table1:一個(gè)名為 table1 的表
content://com.example.app.provider/table2/dataset1:一個(gè)名為 dataset1 的表
content://com.example.app.provider/table2/dataset2:一個(gè)名為 dataset2 的表
content://com.example.app.provider/table3:一個(gè)名為 table3 的表

可以使用以下內(nèi)容 URI 模式:

content://com.example.app.provider/*
//匹配提供程序中的任何內(nèi)容 URI优炬。
content://com.example.app.provider/table2/*:
//匹配表 dataset1 和表 dataset2 的內(nèi)容 URI,但不匹配 table1 或 table3 的內(nèi)容 URI雅宾。
content://com.example.app.provider/table3/#
//匹配 table3 中單個(gè)行的內(nèi)容 URI糊余,
//如 content://com.example.app.provider/table3/6 對(duì)應(yīng)由 6 標(biāo)識(shí)的行的內(nèi)容 URI贬芥。

方法 addURI() 會(huì)將權(quán)限和路徑映射到一個(gè)整型值。 方法 match() 會(huì)返回 URI 的整型值昏苏。switch 語句會(huì)在查詢整個(gè)表與查詢單個(gè)記錄之間進(jìn)行選擇:

public class ExampleProvider extends ContentProvider {
      ...
    // Creates a UriMatcher object.
    private static final UriMatcher sUriMatcher;

    sUriMatcher.addURI("com.example.app.provider", "table3", 1);

    sUriMatcher.addURI("com.example.app.provider", "table3/#", 2);
    ...
    // Implements ContentProvider.query()
    public Cursor query(Uri uri, String[] projection, String selection, 
                String[] selectionArgs, String sortOrder) {
        ...
        switch (sUriMatcher.match(uri)) {
            // If the incoming URI was for all of table3
            case 1:
                if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC";
                break;
            // If the incoming URI was for a single row
            case 2:
                /*
                 Because this URI was for a single row, the _ID value part is
                 present. Get the last path segment from the URI;
                 this is the _ID value.Then, append the value to the WHERE 
                 clause for the query
                 */
                selection = selection + "_ID = " uri.getLastPathSegment();
                break;

            default:
            ...
                // If the URI is not recognized, you should do some error handling here.
        }
        // call the code to actually do the query
    }
創(chuàng)建ContentProvider

在Android中贤惯,如果要?jiǎng)?chuàng)建自己的內(nèi)容提供者的時(shí)候棒掠,需要擴(kuò)展抽象類ContentProvider,并重寫其中定義的各種方法颈墅。然后在AndroidManifest.xml文件中注冊(cè)該ContentProvider雾袱。

創(chuàng)建ContentProvider的步驟:

  1. 創(chuàng)建一個(gè)ContentProvider的子類芹橡。
  1. 定義內(nèi)容Uri
  1. 創(chuàng)建SQLiteOpenHelper的子類,創(chuàng)建一個(gè)用于存儲(chǔ)內(nèi)容的數(shù)據(jù)庫煎殷。
  1. 在ContentProvider的子類中實(shí)現(xiàn)query()腿箩、insert()度秘、update()、delete()唆貌、getType()垢乙、onCreate()方法钩骇。
  1. 在AndroidManifest.xml文件中注冊(cè)自定義的ContentProvider册烈。
    <provider.../>:一般只需要設(shè)置兩個(gè)屬性即可訪問骂倘,一些額外的屬性就是為了設(shè)置訪問權(quán)限而存在的:
    android:name:provider的響應(yīng)類历涝。
    android:authorities:Provider的唯一標(biāo)識(shí),用于Uri匹配堰塌,一般為ContentProvider類的全名分衫。

在實(shí)現(xiàn)ContentProvider的方法時(shí)需要注意一下幾點(diǎn):

  • 所有這些方法(onCreate() 除外)都可由多個(gè)線程同時(shí)調(diào)用蚪战,因此它們必須是線程安全方法。
  • 避免在 onCreate() 中執(zhí)行長時(shí)間操作施籍。將初始化任務(wù)推遲到實(shí)際需要時(shí)進(jìn)行丑慎。
  • 盡管必須實(shí)現(xiàn)這些方法瓤摧,但代碼只需返回要求的數(shù)據(jù)類型,無需執(zhí)行任何其他操作腻异。 例如这揣,可能想防止其他應(yīng)用向某些表插入數(shù)據(jù)。 要實(shí)現(xiàn)此目的给赞,可以忽略 insert() 調(diào)用并返回 0片迅。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市芥挣,隨后出現(xiàn)的幾起案子空免,更是在濱河造成了極大的恐慌,老刑警劉巖鼓蜒,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痹换,死亡現(xiàn)場(chǎng)離奇詭異征字,居然都是意外死亡都弹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門匙姜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畅厢,“玉大人,你說我怎么就攤上這事氮昧】蚨牛” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵咪辱,是天一觀的道長。 經(jīng)常有香客問我椎组,道長油狂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任寸癌,我火速辦了婚禮专筷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒸苇。我一直安慰自己磷蛹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布溪烤。 她就那樣靜靜地躺著味咳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪檬嘀。 梳的紋絲不亂的頭發(fā)上槽驶,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音枪眉,去河邊找鬼捺檬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛贸铜,可吹牛的內(nèi)容都是我干的堡纬。 我是一名探鬼主播聂受,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼烤镐!你這毒婦竟也來了蛋济?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤炮叶,失蹤者是張志新(化名)和其女友劉穎碗旅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镜悉,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祟辟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侣肄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旧困。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖稼锅,靈堂內(nèi)的尸體忽然破棺而出吼具,到底是詐尸還是另有隱情,我是刑警寧澤矩距,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布拗盒,位于F島的核電站,受9級(jí)特大地震影響锥债,放射性物質(zhì)發(fā)生泄漏陡蝇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一赞弥、第九天 我趴在偏房一處隱蔽的房頂上張望毅整。 院中可真熱鬧,春花似錦绽左、人聲如沸悼嫉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戏蔑。三九已至,卻和暖如春鲁纠,著一層夾襖步出監(jiān)牢的瞬間总棵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國打工改含, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留情龄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像骤视,于是被迫代替她去往敵國和親鞍爱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 一专酗、使用ContentProvider(內(nèi)容提供者)共享數(shù)據(jù) ContentProvider在android中的作...
    IT楓閱讀 4,002評(píng)論 0 7
  • Android數(shù)據(jù)存儲(chǔ)(一) Android數(shù)據(jù)存儲(chǔ)(二) Android數(shù)據(jù)存儲(chǔ)(三) Android數(shù)據(jù)存儲(chǔ)(...
    前端develop閱讀 2,346評(píng)論 0 3
  • 這篇主要介紹下ContentProvider如何實(shí)現(xiàn)共享數(shù)據(jù)睹逃、及ContentResolver如何訪問其他進(jìn)程等數(shù)...
    朋永閱讀 2,496評(píng)論 0 5
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,322評(píng)論 25 707
  • 不可抗力具有獨(dú)特的魔力,它的力量摧枯拉朽祷肯。我小時(shí)候總做的一個(gè)夢(mèng)沉填,它一直都在預(yù)警著一件可怕的事情。這很奇妙佑笋,就好像到...
    DEBRAH閱讀 276評(píng)論 0 0