Android必知必會的四大組件 -- ContentProvider篇

前言

做爲四大組件之一,它的地位絕對不允許輕視的。可是咱們在哪裏有用到過他呢?其實很簡單,你在使用app時,是否是常常的會詢問你是否開啓通信錄的訪問,若是你贊成了,這個時候ContentProvider就發揮了他的做用。java

思惟導圖

使用方法

如下經過對通信錄的操做讓讀者來更清晰的瞭解。 可是共享的數據不該該被咱們隨意的更改,若是有這樣的須要,把這些數據存儲在本地,而後再進行這樣的操縱更爲合適,因此下方的演示代碼只包含了查詢的功能。不過由於調用外部的數據,通常來講須要權限申請。android

我已經在Android工具包中已經集成了權限申請的工具類。git

// 數據查詢
try (Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null)) {
        while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                Log.e(TAG, name + " ;" + number);
            }
} catch (Exception e) {
            e.printStackTrace();
}
複製代碼

文件共享的基礎

其實在ContentProvider中使用的通訊機制依舊是Binder,而文件定位則是經過URI的方式來完成,因此主講的一部份內容就是URI的格式解析。github

URI

格式:[scheme:][//host:port][path][?query]
複製代碼

這一個URI的格式,爲了方便起見,咱們直接拿一個域名來分析它。數據庫

》》例題《《bash

連接地址:juejin.im/user/5e2659…app

  1. scheme:https,也就是協議
  2. host:juejin.im,域名地址
  3. port:默認80,端口號
  4. path:/user/5e2659e15188254d95242d4b,文件路徑/控制器路徑
  5. query:好比 ?userId=x&message=y,就是咱們javaWeb中的一些請求數據。

固然在咱們的ContentProvider存在必定的誤差。ide

文件位置:content://com.clericyi.file/message/id工具

  1. scheme:content://,這是Android的固定路徑
  2. authority:com.clericyi.file,也就是用於標示惟一的ContentProvider
  3. path:message,也就是對應的表名
  4. id:對應表中的數據

幫助工具

UriMatcher

這是一個內置的URI工具,他一共只提供了兩個開放方法addURI()match(),這是一個用於幫助匹配ContentProviderURI的方法,針對的是除去id前半段匹配。post

// 用法
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
String authority = "com.clericyi.file";
String path = "message";
int URI_CODE = 1;
// 將URI和URI_CODE關聯
uriMatcher.addURI(authority, path, URI_CODE);
// 用於獲取對應的URI_CODE
uriMatcher.match(Uri.parse("content://com.clericyi.file/message"))
複製代碼

ContentUris

一樣是一個內置的工具類,提供的方法有parseId()appendId()withAppendedId()removeId(),針對的就是id

Uri uri = Uri.parse("content://com.clericyi.file/messag");
// 鏈接id
uri = ContentUris.withAppendedId(uri, CODE);
// 去除id
uri = ContentUris.removeId(uri);
// 獲取id
long num = ContentUris.parseId(uri);
複製代碼

ContentProvider代碼流程導讀

工做流程:

從上文中的電話簿號碼查詢入手
(1)獲取一個ContentResolver,並調用query(),內部參數不少,基本和數據庫查詢的參數保持一致。
(2)在query()方法中會調用到acquireUnstableProvider(uri)的方法,而返回值IContentProvider,對應就是一個Binder機制
(3)內部經過對uri的一些解析,找獲得對應的文件,而後轉化成Cursor遊標
(4)經過遊標的滑動讀取,就轉化成了咱們的數據
複製代碼

query()內部參數分析

  • uri:位置暴露的惟一表示。
  • projection:返回列(字段)
  • selection:設置條件,至關於數據庫中的where
  • selectionArgs:和selection聯合使用,用於替換selection中的 ?
  • sortOrder:排列順序,至關於數據庫中的order by
所有參數使用實例:
contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI
    , new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME}
    , android.provider.ContactsContract.Contacts.DISPLAY_NAME + "=?"
    , new String[]{"小易"}
    , android.provider.ContactsContract.Contacts.DISPLAY_NAME + " DESC"); // 中間存在空格,默認爲ASC,升序。
複製代碼

最後的話這片文章就不寫關於聯合Database的使用了,應該容易冗長,專門找了一篇文章給讀者們拿來專門學習ContentProvider的使用。跳轉連接

另外也算是個人一種突破,畢竟一天發了四篇博客,雖然兩篇其實我只是重構了一下,可是着實仍是有點累的。

以上就是個人學習成果,若是有什麼我沒有思考到的地方或是文章內存在錯誤,歡迎與我分享。


相關文章推薦:

Android必知必會的四大組件 -- Activity篇

Android必知必會的四大組件 -- Broadcast Receiver篇

Android必知必會的四大組件 -- Service篇

相關文章
相關標籤/搜索