前言
作為四大元件之一,它的地位絕對不容許輕視的。但是我們在哪裡有用到過他呢?其實很簡單,你在使用app時,是不是經常的會詢問你是否開啟通訊錄的訪問,如果你同意了,這個時候ContentProvider
就發揮了他的作用。
思維導圖
使用方法
以下通過對通訊錄的操作讓讀者來更清晰的瞭解。 但是共享的資料不應該被我們隨意的更改,如果有這樣的需要,把這些資料儲存在本地,然後再進行這樣的操縱更為合適,所以下方的演示程式碼只包含了查詢的功能。不過因為呼叫外部的資料,一般來說需要許可權申請。
我已經在Android工具包中已經整合了許可權申請的工具類。
// 資料查詢
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
的格式解析。
URI
格式:[scheme:][//host:port][path][?query]
複製程式碼
這一個URI
的格式,為了方便起見,我們直接拿一個域名來分析它。
》》例題《《
- scheme:
https
,也就是協議 - host:
juejin.im
,域名地址 - port:預設80,埠號
- path:
/user/5e2659e15188254d95242d4b
,檔案路徑/控制器路徑 - query:比如
?userId=x&message=y
,就是我們javaWeb
中的一些請求資料。
當然在我們的ContentProvider
存在一定的偏差。
檔案位置:content://com.clericyi.file/message/id
- scheme:
content://
,這是Android的固定路徑 - authority:
com.clericyi.file
,也就是用於標示唯一的ContentProvider
- path:
message
,也就是對應的表名 - id:對應表中的資料
幫助工具
UriMatcher
這是一個內建的URI
工具,他一共只提供了兩個開放方法addURI()
、match()
,這是一個用於幫助匹配ContentProvider
中URI
的方法,針對的是除去id
前半段匹配。
// 用法
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的使用。跳轉連結
另外也算是我的一種突破,畢竟一天發了四篇部落格,雖然兩篇其實我只是重構了一下,但是著實還是有點累的。
以上就是我的學習成果,如果有什麼我沒有思考到的地方或是文章記憶體在錯誤,歡迎與我分享。
相關文章推薦: