Android中ContentProvider组件数据共享
ContentProvider的功能和意義:
主要用于對(duì)外共享數(shù)據(jù),也就是通過(guò)ContentProvider把應(yīng)用中的數(shù)據(jù)共享給其他應(yīng)用訪問(wèn),其他應(yīng)用可以通過(guò)ContentProvider對(duì)指定應(yīng)用中的數(shù)據(jù)進(jìn)行操作。
實(shí)現(xiàn)在不同應(yīng)用程序之間共享數(shù)據(jù),在應(yīng)用程序之間交換數(shù)據(jù),一個(gè)應(yīng)用程序A把自己的數(shù)據(jù)通過(guò)ContentProvider暴露給其他程序使用B,B就可以通過(guò)ContentResolver來(lái)操作ContentProvider暴露的數(shù)據(jù),包括增,刪,查,改
1、ContentProvider使用表的形式來(lái)組織數(shù)據(jù)
無(wú)論數(shù)據(jù)的來(lái)源是什么,ContentProvider都會(huì)認(rèn)為是一種表,然后把數(shù)據(jù)組織成表格
2、ContentProvider提供的方法
public boolean onCreate() 在創(chuàng)建ContentProvider時(shí)調(diào)用
public Cursor query(Uri, String[], String, String[], String) 用于查詢指定Uri的ContentProvider,返回一個(gè)Cursor
public Uri insert(Uri, ContentValues) 用于添加數(shù)據(jù)到指定Uri的ContentProvider中
public int update(Uri, ContentValues, String, String[]) 用于更新指定Uri的ContentProvider中的數(shù)據(jù)
public int delete(Uri, String, String[]) 用于從指定Uri的ContentProvider中刪除數(shù)據(jù)
public String getType(Uri) 用于返回指定的Uri中的數(shù)據(jù)的MIME類型
*如果操作的數(shù)據(jù)屬于集合類型,那么MIME類型字符串應(yīng)該以vnd.android.cursor.dir/開頭。
例如:要得到所有person記錄的Uri為content://contacts/person,那么返回的MIME類型字符串為"vnd.android.cursor.dir/person"。
*如果要操作的數(shù)據(jù)屬于非集合類型數(shù)據(jù),那么MIME類型字符串應(yīng)該以vnd.android.cursor.item/開頭。
例如:要得到id為10的person記錄的Uri為content://contacts/person/10,那么返回的MIME類型字符串應(yīng)為"vnd.android.cursor.item/person"。
3、每個(gè)ContentProvider都有一個(gè)公共的URI,這個(gè)URI用于表示這個(gè)ContentProvider所提供的數(shù)據(jù)。Android所提供的ContentProvider都存放在android.provider包當(dāng)中
二,Uri類簡(jiǎn)介
1,為系統(tǒng)的每一個(gè)資源給其一個(gè)名字,比方說(shuō)通話記錄。每個(gè)ContentProvider都有一個(gè)公共的URI,這個(gè)URI用于表示這個(gè)ContentProvider所提供的數(shù)據(jù)。
例Uri:content://com.hust.uri/words
Uri指定了將要操作的ContentProvider,其實(shí)可以把一個(gè)Uri看作是一個(gè)網(wǎng)址,我們把Uri分為三部分。
第一部分是"content://"。可以看作是網(wǎng)址中的"http://"。
第二部分是主機(jī)名或authority,用于唯一標(biāo)識(shí)這個(gè)ContentProvider,外部應(yīng)用需要根據(jù)這個(gè)標(biāo)識(shí)來(lái)找到它。可以看作是網(wǎng)址中的主機(jī)名,比如"blog.csdn.net"。
第三部分是路徑名,資源部分,用來(lái)表示將要操作的數(shù)據(jù)。
例:content://com.hust.uri/words
訪問(wèn)的資源是words/2,意味著訪問(wèn)word數(shù)據(jù)表中的全部數(shù)據(jù)
例:content://com.hust.uri/words/2
訪問(wèn)的資源是words/2,意味著訪問(wèn)word數(shù)據(jù)中ID為2的記錄
例:content://com.hust.uri/words/2/word
訪問(wèn)的資源是words/2,意味著訪問(wèn)word數(shù)據(jù)中ID為2的記錄的word字段
把一個(gè)字符串轉(zhuǎn)換成Uri,是Uri類的靜態(tài)方法:Uri uri = Uri.parse("content://com.hust.uri/contact")
2,UriMatcher類使用介紹
因?yàn)閁ri代表了要操作的數(shù)據(jù),所以我們經(jīng)常需要解析Uri,并從Uri中獲取數(shù)據(jù)。Android系統(tǒng)提供了兩個(gè)用于操作Uri的工具類,分別為UriMatcher和ContentUris
UriMatcher類用于匹配Uri:
?A,void addURI(String authority,String path,int code)向UriMatcher中注冊(cè)Uri,authority和path組成一個(gè)Uri,code代表該Uri對(duì)應(yīng)的標(biāo)識(shí)碼
?B,int match(Uri uri);根據(jù)前面注冊(cè)的Uri來(lái)判斷指定的Uri對(duì)應(yīng)的標(biāo)識(shí)碼
UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH); matcher.addURI("com.hust.uri","words",1); matcher.addURI("com.hust.uri","words/#",2); com.hust.uri/words/#表示words下的所有數(shù)據(jù)uri的表示為2
匹配結(jié)果如下:
matcher.match(Uri.parse("content://com.hust.uri/words")); //返回標(biāo)識(shí)碼1 matcher.match(Uri.parse("content://com.hust.uri/words/2")); //返回標(biāo)識(shí)碼2 matcher.match(Uri.parse("content://com.hust.uri/words/10")); //返回標(biāo)識(shí)碼2注冊(cè)完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法對(duì)輸入的Uri進(jìn)行匹配,如果匹配就返回匹配碼,匹配碼是調(diào)用addURI()方法傳入的第三個(gè)參數(shù)
3,ContentUris類使用介紹
ontentUris類用于操作Uri路徑后面的ID部分,它有兩個(gè)比較實(shí)用的方法:
withAppendedId(uri, id)用于為路徑加上ID部分:
Uri uri = Uri.parse("content://com.hust.uri.personprovider/person/10") long personid = ContentUris.parseId(uri);//獲取的結(jié)果為:10
三,開發(fā)ContentProvider
1,開發(fā)一個(gè)ContentProvider子類,繼承ContentProvider,實(shí)現(xiàn)query,insert,update,delete等方法
2,在Manifest.xml清單文件中注冊(cè)該ContentProvider,指定其Android:authorities屬性
public class FirstProvider extends ContentProvider {// 第一次創(chuàng)建該ContentProvider時(shí)調(diào)用該方法@Overridepublic boolean onCreate(){System.out.println("===onCreate方法被調(diào)用===");return true;}// 該方法的返回值代表了該ContentProvider所提供數(shù)據(jù)的MIME類型@Overridepublic String getType(Uri uri){System.out.println("~~getType方法被調(diào)用~~");return null;}// 實(shí)現(xiàn)查詢方法,該方法應(yīng)該返回查詢得到的Cursor@Overridepublic Cursor query(Uri uri, String[] projection, String where,String[] whereArgs, String sortOrder){System.out.println(uri + "===query方法被調(diào)用===");System.out.println("where參數(shù)為:" + where);return null;}// 實(shí)現(xiàn)插入的方法,該方法應(yīng)該新插入的記錄的Uri@Overridepublic Uri insert(Uri uri, ContentValues values){System.out.println(uri + "===insert方法被調(diào)用===");System.out.println("values參數(shù)為:" + values);return null;}// 實(shí)現(xiàn)刪除方法,該方法應(yīng)該返回被刪除的記錄條數(shù)@Overridepublic int delete(Uri uri, String where, String[] whereArgs){System.out.println(uri + "===delete方法被調(diào)用===");System.out.println("where參數(shù)為:" + where);return 0;}// 實(shí)現(xiàn)刪除方法,該方法應(yīng)該返回被更新的記錄條數(shù)@Overridepublic int update(Uri uri, ContentValues values, String where,String[] whereArgs){System.out.println(uri + "===update方法被調(diào)用===");System.out.println("where參數(shù)為:"+ where + ",values參數(shù)為:" + values);return 0;} }
這4個(gè)方法用于供其他應(yīng)用通過(guò)ContentProvider調(diào)用。
注冊(cè)ContentProvider:
<!-- 注冊(cè)一個(gè)ContentProvider --><providerandroid:exported="true"android:name=".FirstProvider"android:authorities="org.providers.firstprovider"></provider> android:authorities屬性是一定要配置的,指定該ContentProvider對(duì)應(yīng)的Uri
上面配置指定了該ContentProvider被綁定到“content://org.providers.firstprovider”,這意味著其他應(yīng)用的ContentResovler向該Uri執(zhí)行query,insert,update,delete方法時(shí),實(shí)際上是調(diào)用該ContentProvider的query,insert,update,delete方法,ContentResovler調(diào)用方法時(shí)將參數(shù)傳給ContentProvider對(duì)應(yīng)的方法參數(shù)。
四,開發(fā)contentResovler
通過(guò)getContentResolver()方法獲取ContentResolver對(duì)象,獲取ContentResolver對(duì)象之后,接下來(lái)可調(diào)用query,insert,update,delete方法了,實(shí)際上調(diào)用的是指定Uri對(duì)應(yīng)的ContentProvider的query,insert,update,delete方法
例:界面4個(gè)按鈕,分別對(duì)應(yīng)增刪查改功能:
public class FirstResolver extends Activity {ContentResolver contentResolver;//聲明變量Uri uri = Uri.parse("content://org.providers.firstprovider/");//FirstProvider的Uri@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 獲取系統(tǒng)的ContentResolver對(duì)象contentResolver = getContentResolver();}public void query(View source){// 調(diào)用ContentResolver的query()方法。// 實(shí)際返回的是該Uri對(duì)應(yīng)的ContentProvider的query()的返回值Cursor c = contentResolver.query(uri, null, "query_where", null, null);Toast.makeText(this, "遠(yuǎn)程ContentProvide返回的Cursor為:" + c,Toast.LENGTH_LONG).show();}public void insert(View source){ContentValues values = new ContentValues();values.put("name", "fkjava");// 調(diào)用ContentResolver的insert()方法。// 實(shí)際返回的是該Uri對(duì)應(yīng)的ContentProvider的insert()的返回值Uri newUri = contentResolver.insert(uri, values);Toast.makeText(this, "遠(yuǎn)程ContentProvide新插入記錄的Uri為:"+ newUri, Toast.LENGTH_LONG).show();}public void update(View source){ContentValues values = new ContentValues();values.put("name", "fkjava");// 調(diào)用ContentResolver的update()方法。// 實(shí)際返回的是該Uri對(duì)應(yīng)的ContentProvider的update()的返回值int count = contentResolver.update(uri, values, "update_where", null);Toast.makeText(this, "遠(yuǎn)程ContentProvide更新記錄數(shù)為:"+ count, Toast.LENGTH_LONG).show();}public void delete(View source){// 調(diào)用ContentResolver的delete()方法。// 實(shí)際返回的是該Uri對(duì)應(yīng)的ContentProvider的delete()的返回值int count = contentResolver.delete(uri, "delete_where", null);Toast.makeText(this, "遠(yuǎn)程ContentProvide刪除記錄數(shù)為:"+ count, Toast.LENGTH_LONG).show();}
五,ContentProvider與ContentResolver的關(guān)系
ContentResolver對(duì)指定的Uri指定CRUD等數(shù)據(jù)操作,但是Uri并不是真正的數(shù)據(jù)中心,因此這些CRUD操作會(huì)委托給Uri對(duì)應(yīng)的ContentProvider來(lái)實(shí)現(xiàn)。通常來(lái)說(shuō),A應(yīng)用通過(guò)ContentResolver執(zhí)行CRUD操作,這些操作都需要指定Uri參數(shù),Android系統(tǒng)就根據(jù)該Uri找到對(duì)應(yīng)的ContentProvider(該ContentProvider通常屬于B應(yīng)用),ContentProvider則負(fù)責(zé)實(shí)現(xiàn)CRUD方法,完成對(duì)底層數(shù)據(jù)的增刪改查等操作,這樣A應(yīng)用就可以訪問(wèn),修改B應(yīng)用的數(shù)據(jù)了
總結(jié)
以上是生活随笔為你收集整理的Android中ContentProvider组件数据共享的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android数据存储的三种方式-Sha
- 下一篇: Android中的Service组件详解