Android四大組件之ContentProvider

概述

為了實(shí)現(xiàn)在不同App之間共享數(shù)據(jù)的需求,Android提供了ContentProvider。

ContentProvider使用

ContentProvider是不同App之間進(jìn)行數(shù)據(jù)交換的標(biāo)準(zhǔn)API。當(dāng)一個(gè)App需要把自己的數(shù)據(jù)暴露給其它App使用時(shí),該App可以通過提供ContentProvider來實(shí)現(xiàn)。

ContentProvider使用中包含以下內(nèi)容:

  • 統(tǒng)一資源標(biāo)識(shí)符(URI): 外部進(jìn)程通過URI找到對(duì)應(yīng)的ContentProvider和相關(guān)數(shù)據(jù),再進(jìn)行數(shù)據(jù)操作。
    例如:content://com.android.myprovider/person/1
    (1) content:// :主題名(Schema),URI的前綴。暴露和訪問ContentProvider的協(xié)議默認(rèn)是content://。
    (2) com.android.myprovider :授權(quán)信息(Authority):唯一標(biāo)識(shí)符。根據(jù)這個(gè)信息找到操作哪個(gè)ContentProvider。
    (3) person :表名(Path)。指向數(shù)據(jù)庫中的某個(gè)表名。當(dāng)訪問不同資源時(shí),該部分是動(dòng)態(tài)改變的。
    (4) 1 :記錄(ID)。表中ID為1的記錄。若無指定,則返回全部記錄。

  • MIME數(shù)據(jù)類型 :指定某個(gè)擴(kuò)展名的文件用某種應(yīng)用程序來打開。
    eg: text/html -- >.html文件采用text程序打開。

  • 繼承ContentProvider后,需要重寫的方法:
    (1) onCreate() :當(dāng)其它應(yīng)用通過ContentResolver第一次訪問ContentProvider時(shí)被調(diào)用,負(fù)責(zé)數(shù)據(jù)庫的創(chuàng)建和更新。
    (2) query() :查詢。
    (3) update() :更新。
    (4) insert() :插入。
    (5) delete() :刪除。
    (6) getType() :用于返回當(dāng)前Uri所代表的數(shù)據(jù)的MIME類型。兩種類型:單條記錄--> vnd.android.cursor.item/自定義。多條記錄-->vnd.android.cursor.dir/自定義.

  • 在AndroidManifest.xml注冊如下:

<provider android:name=".MyProvider"
          android:authorities="com.android.myprovider" />

ContentResolver使用

ContentProvider類并不會(huì)直接與外部進(jìn)程交互,而是通過ContentResolver來操作ContentProvider所暴露的數(shù)據(jù)。

  • getContentResolver(): 獲得ContentResolver對(duì)象后,可以調(diào)用下面的方法來操作數(shù)據(jù)。
  • query():查詢。
  • update():更新。
  • insert():插入。
  • delete():刪除。
ContentResolver resolver =  getContentResolver(); 

Uri uri = Uri.parse("content://com.android.providers.test/person"); 
 
Cursor cursor = resolver.query(uri, null, "query_where", null, null); 

ContentObserver使用

觀察ContentProvider中的數(shù)據(jù)變化,并通知數(shù)據(jù)訪問者。

//注冊ContentObserver
getContentResolver().registerContentObserver(uri);

//當(dāng)ContentProvider數(shù)據(jù)發(fā)生變化時(shí),通知該ContentProvider數(shù)據(jù)的訪問者
public class MyContentProvider extends ContentProvider { 
    public Uri insert(Uri uri, ContentValues values) { 
      db.insert("person", "id", values); 
      getContext().getContentResolver().notifyChange(uri, null); 
   } 
}

//解除觀察者
 getContentResolver().unregisterContentObserver(uri);

UriMatcher使用

為了確定ContentProvider實(shí)際能處理的Uri,以及確定每個(gè)方法中Uri參數(shù)所操作的數(shù)據(jù),Android系統(tǒng)提供了該工具類。

  • addURI(String authority,String path,int code)方法:用于向UriMatcher對(duì)象注冊Uri。其中authority和path組成一個(gè)Uri,code代表該Uri對(duì)應(yīng)的標(biāo)識(shí)碼。

  • int match(Uri uri):根據(jù)前面注冊的Uri來判斷指定Uri對(duì)應(yīng)的標(biāo)識(shí)碼。如果找不到匹配的標(biāo)識(shí)碼,返回-1。

    //初始化UriMatcher對(duì)象
    //常量UriMatcher.NO_MATCH  = 不匹配任何路徑的返回碼
    UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); 

    //在ContentProvider 中注冊URI
    int URI_CODE_1 = 1;
    int URI_CODE_2 = 2;
    matcher.addURI("com.android.myprovider", "person1", URI_CODE_1); 
    matcher.addURI("com.android.myprovider", "person2", URI_CODE_2); 

@Override   
    public String getType(Uri uri) {   
      Uri uri = Uri.parse(" content://com.android.myprovider/person1");   

      switch(matcher.match(uri)){   
        case URI_CODE_1:   
          return tablePerson1;   
        case URI_CODE_2:   
          return tablePerson2;
    }   
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容