概述
為了實(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;
}
}