您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Android中怎么創建自己的內容提供器”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Android中怎么創建自己的內容提供器”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
創建內容提供器的步驟
前面已經提到過,如果想要實現跨程序共享數據的功能,官方推薦的方式就是使用內容提供器,可以通過新建一個類去繼承 ContentProvider 的方式來創建一個自己的內容提供器。 ContentProvider 類中有六個抽象方法,我們在使用子類繼承它的時候,需要將這六個方法全 部重寫。新建 MyProvider 繼承自 ContentProvider,代碼如下所示:
public class MyProvider extends ContentProvider { @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public String getType(Uri uri) { return null; } }
在這六個方法中,相信大多數你都已經非常熟悉了,我再來簡單介紹一下吧。
1. onCreate()
初始化內容提供器的時候調用。通常會在這里完成對數據庫的創建和升級等操作, 返回 true 表示內容提供器初始化成功,返回 false 則表示失敗。注意,只有當存在 ContentResolver 嘗試訪問我們程序中的數據時,內容提供器才會被初始化。
2. query()
從內容提供器中查詢數據。使用 uri 參數來確定查詢哪張表,projection 參數用于確 定查詢哪些列,selection 和 selectionArgs 參數用于約束查詢哪些行,sortOrder 參數用于 對結果進行排序,查詢的結果存放在 Cursor 對象中返回。
3. insert()
向內容提供器中添加一條數據。使用 uri 參數來確定要添加到的表,待添加的數據 保存在 values 參數中。添加完成后,返回一個用于表示這條新記錄的 URI。
4. update()
更新內容提供器中已有的數據。使用 uri 參數來確定更新哪一張表中的數據,新數 據保存在 values 參數中,selection 和 selectionArgs 參數用于約束更新哪些行,受影響的 行數將作為返回值返回。
5. delete()
從內容提供器中刪除數據。使用 uri 參數來確定刪除哪一張表中的數據,selection和 selectionArgs 參數用于約束刪除哪些行,被刪除的行數將作為返回值返回。
6. getType()
根據傳入的內容 URI 來返回相應的 MIME 類型。 可以看到,幾乎每一個方法都會帶有 Uri 這個參數,這個參數也正是調用 ContentResolver的增刪改查方法時傳遞過來的。而現在,我們需要對傳入的 Uri 參數進行解析,從中分析出 調用方期望訪問的表和數據。
回顧一下,一個標準的內容 URI 寫法是這樣的:
content://com.example.app.provider/table1
這就表示調用方期望訪問的是 com.example.app 這個應用的 table1 表中的數據。除此之 外,我們還可以在這個內容 URI 的后面加上一個 id,如下所示:
content://com.example.app.provider/table1/1
這就表示調用方期望訪問的是 com.example.app 這個應用的 table1 表中 id 為 1 的數據。 內容 URI 的格式主要就只有以上兩種,以路徑結尾就表示期望訪問該表中所有的數據,以 id 結尾就表示期望訪問該表中擁有相應 id 的數據。我們可以使用通配符的方式來分別匹 配這兩種格式的內容 URI,規則如下。
1. *:表示匹配任意長度的任意字符
2. #:表示匹配任意長度的數字 所以,一個能夠匹配任意表的內容 URI 格式就可以寫成:
content://com.example.app.provider/*
而一個能夠匹配 table1 表中任意一行數據的內容 URI 格式就可以寫成:
content://com.example.app.provider/table1/#
接著,我們再借助 UriMatcher 這個類就可以輕松地實現匹配內容 URI 的功能。UriMatcher 中提供了一個 addURI()方法,這個方法接收三個參數,可以分別把權限、路徑和一個自定義 代碼傳進去。這樣,當調用 UriMatcher 的 match()方法時,就可以將一個 Uri 對象傳入,返 回值是某個能夠匹配這個 Uri 對象所對應的自定義代碼,利用這個代碼,我們就可以判斷出 調用方期望訪問的是哪張表中的數據了。修改 MyProvider 中的代碼,如下所示:
public class MyProvider extends ContentProvider { public static final int TABLE1_DIR = 0; public static final int TABLE1_ITEM = 1; public static final int TABLE2_DIR = 2; public static final int TABLE2_ITEM = 3; private static UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR); uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM); uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM); uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM); } …… @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { switch (uriMatcher.match(uri)) { case TABLE1_DIR: // 查詢table1表中的所有數據 break; case TABLE1_ITEM: // 查詢table1表中的單條數據 break; case TABLE2_DIR: // 查詢table2表中的所有數據 break; case TABLE2_ITEM: // 查詢table2表中的單條數據 break; default: break; } …… } …… }
可以看到,MyProvider 中新增了四個整型常量,其中 TABLE1_DIR 表示訪問 table1 表 中的所有數據,TABLE1_ITEM 表示訪問 table1 表中的單條數據,TABLE2_DIR 表示訪問 table2 表中的所有數據,TABLE2_ITEM 表示訪問 table2 表中的單條數據。接著在靜態代碼 塊里我們創建了 UriMatcher 的實例,并調用 addURI()方法,將期望匹配的內容 URI 格式傳 遞進去,注意這里傳入的路徑參數是可以使用通配符的。然后當 query()方法被調用的時候, 就會通過 UriMatcher 的 match()方法對傳入的 Uri 對象進行匹配,如果發現 UriMatcher 中某 個內容 URI 格式成功匹配了該 Uri 對象,則會返回相應的自定義代碼,然后我們就可以判斷 出調用方期望訪問的到底是什么數據了。
上述代碼只是以 query()方法為例做了個示范,其實 insert()、update()、delete()這幾個方 法的實現也是差不多的,它們都會攜帶 Uri 這個參數,然后同樣利用 UriMatcher 的 match() 方法判斷出調用方期望訪問的是哪張表,再對該表中的數據進行相應的操作就可以了。
除此之外,還有一個方法你會比較陌生,即 getType()方法。它是所有的內容提供器都必 須提供的一個方法,用于獲取 Uri 對象所對應的 MIME 類型。一個內容 URI 所對應的 MIME 字符串主要由三部分組分,Android 對這三個部分做了如下格式規定。
1. 必須以 vnd 開頭。
2. 如果內容 URI 以路徑結尾,則后接 android.cursor.dir/,如果內容 URI 以 id 結尾, 則后接 android.cursor.item/。
3. 最后接上 vnd.<authority>.<path>。
所以,對于 content://com.example.app.provider/table1 這個內容 URI,它所對應的 MIME
類型就可以寫成:
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
對于 content://com.example.app.provider/table1/1 這個內容 URI,它所對應的 MIME 類型 就可以寫成:
vnd.android.cursor.item/vnd. com.example.app.provider.table1
現在我們可以繼續完善 MyProvider 中的內容了,這次來實現 getType()方法中的邏輯, 代碼如下所示:
public class MyProvider extends ContentProvider { …… @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case TABLE1_DIR: return "vnd.android.cursor.dir/vnd.com.example.app.provider. table1"; case TABLE1_ITEM: return "vnd.android.cursor.item/vnd.com.example.app.provider. table1"; case TABLE2_DIR: return "vnd.android.cursor.dir/vnd.com.example.app.provider. table2"; case TABLE2_ITEM: return "vnd.android.cursor.item/vnd.com.example.app.provider. table2"; default: break; } return null; } }
讀到這里,這篇“Android中怎么創建自己的內容提供器”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。