自定義ContentProvider的一些細節探究

http://blog.csdn.net/sadfishsc/article/details/7419573html

 

1.   適用範圍

對於什麼狀況下才會用到自定義的ContentProvider,官方文檔的Dev Guide是這樣描述的:android

若是你想要提供如下的一種或幾種特性的時候你才須要構造一個ContentProvider:web

 

  • 你想要爲其它的應用提供複雜的數據或者文件;
  • 你想容許用戶從你的應用中拷貝複雜的數據到其它的應用中;
  • 你想要使用搜索框架來提供自定義的搜索策略。

 

你徹底不須要ContentProvider來調用一個SQLite數據庫,若是這種調用徹底在你本身的應用之中。數據庫

 

也就是說,ContentProvider的做用是爲別的應用調用本應用中的數據或者文件提供接口,而它也是惟一的跨應用數據傳遞的接口。若是僅僅是同一個應用中的數據傳遞,則徹底沒有必要使用到自定義的ContentProvider。框架

另外一方面,雖然ContentProvider也能組織文件數據或者SharedPreferences(其實也是文件數據)這種數據,但大多數狀況下ContentProvider是做爲SQLite數據庫的調用接口來被繼承的。其緣由大概是在於重寫的query()方法始終須要返回Cursor,而Cursor做爲數據庫數據的容器,並無提供直接往Cursor中寫入數據的方法。ide

2.   大致實現步驟

1.      建立一個數據源,例如繼承SQLiteOpenHelper建立一個SQLite數據庫;測試

2.      建立一個繼承自ContentProvider的類,並重寫insert、delete、query、update、getType、onCreate方法,在這些方法中實現對數據源的操做;ui

3.      在AndroidManifest.xml文件中添加<provider>標籤,兩個必寫的屬性是android:name和android:authorities;spa

4.      在本應用或者其它應用的Activity、Service等組件中使用ContentResolver經過對應的URI來操做該自定義ContentProvider。.net

3.   URI

Android各類類型的URI基本上都是有固定格式的,對於ContentProvider而言,通常形如

content://com.test.cp.MyProvider/phone/1

的URI,其中:

content://是固定字段,必需;

com.test.cp.MyProvider表示authority,是AndroidManifest.xml文件中<provider>標籤的android:authorities屬性值,或者是遠程數據源的主機名,必需;

phone/1表示path,是數據源路徑,非必需,其中的phone對於數據庫來講能夠視爲表名,1表示的是該條數據的編號,若是沒有則通常認爲是返回當前路徑(當前表)中的全部數據。

另外還能夠根據本身的須要來進一步定義後續的字段。

4.   onCreate方法與構造方法

ContentProvider沒有顯式地執行初始化的語句,所以即使是重寫了它的構造方法也不會被執行。它的初始化代碼通常都寫在onCreate方法中。可是網上的例子中也有部分初始化代碼被寫在了靜態域之中(主要是關於UriMatcher的初始化代碼)。不過通過本人測試發現,把這些放在靜態域中的代碼移到onCreate方法中也不會影響程序的運行。

另外須要注意的是必須把onCreate方法的返回值該爲true,該ContentProvider才能被加載。

5.   UriMatch對象

UriMatch對象的做用是將URI匹配到對應的表(就數據庫而言),其使用步驟以下:

1.        經過new  UriMatcher(UriMatcher.NO_MATCH); 實例化,常量NO_MATCH做爲參數表示不匹配任何URI;

2.        實例化後調用addURI方法註冊URI,該方法有三個參數,分別須要傳入URI字符串的authority部分、path部分以及自定義的整數code三者;

3.        在其它地方調用match方法匹配相應的URI,須要傳入Uri做爲惟一的參數,返回上述自定義的code值。

至於其初始化的位置,如前所述,網上絕大多數示例都將其放入靜態域中實例化,緣由不明。實際上放到onCreate方法中也沒什麼問題。

6.   getType方法

ContentProvider必須重寫的6個方法中,除了初始化方法onCreate以及數據操做的4個方法之外,還有一個getType方法。它的做用是根據URI返回該URI所對應的數據的MIME類型字符串。這種字符串的格式分爲兩段:「A/B」。其中A段是固定的,集合類型(如多條數據)必須是vnd.android.cursor.dir,非集合類型(如單條數據)必須是vnd.android.cursor.item;B段能夠是自定義的任意字符串;A、B兩段經過「/」隔開。這個MIME類型字符串的做用是要匹配AndroidManifest.xml文件<activity>標籤下<intent-filter>標籤的子標籤<data>的屬性android:mimeType。若是不一致,則會致使對應的Activity沒法啓動。

7.   notifyChange方法

網上的某些示例中在重寫insert、delete、update、query方法對數據的操做結束以後,總會加一句代碼:

getContext().getContentResolver().notifyChange(uri,null);

其做用是通知在ContentResolver中註冊了該URI的ContentObserver,這個URI對應的數據源發生變化了。其具體用法參見下面的連接:

http://blog.csdn.net/zhf198909/article/details/6903708

另外,通知變化對於ContentProvider來講並非必需的,根據實際功能的須要,自定義的ContentProvider中多數狀況下並不須要這句代碼。

8.   示例

http://www.cnblogs.com/chenglong/articles/1892029.html

相關文章
相關標籤/搜索