如何創建自己的ContentProvider

作爲ANDROIDL四大組件(Compenent:Activity, Service, BreadcaseReceiver,ContentProvider)之一的Content provider,爲其它應用程序(也可以是提供該Content provider的應用程序)提供了一個接口一致數據儲存模型。通過該接口,你可以方便地提取你想要的數據,修改或者是刪除都會變得相當方便。依照 ANDROI組件模型的原理,把數據儲存與數據顯示分離天來,這不但提高了組件重用性,也同時提供更高的完全性(每一個Content Provider都有自己的許可屬性)。作爲數據儲存的後端,你可以使用有Sqlite3保存數據,也可以使用文件系統保存,甚至是使用網絡;後端的多樣 性給得程序的設計更富有彈性。

今天結合自己開發的經驗,總結一下實現Content Provider的幾點經驗,不足之處,歡迎討論

 

通過擴展 ContentProvider 類來創建一個新的 Content Provider 。重寫 onCreate 方法來打開或初始化你要通過這個 Provider 提供的底層數據源。新的 Content Provider 的框架代碼如下所示:

 

import android.content.*;

import android.database.Cursor;

import android.net.Uri;

import android.database.SQLException;

 

public class MyProvider extends ContentProvider

{

@Override

public boolean onCreate()

{

// TODO: Construct the underlying database.

return true;

}

}

 

你還應該暴露一個公共的靜態變量 CONTENT_URI ,來返回這個 Provider URI

 

Content URI Provider 間必須是獨一無二的,所以,一個好的習慣是: URI 路徑值使用包名。定義一個 Content Provider URI 的通用格式是:

 

content://com.<CompanyName>.provider.<ApplicationName>/<DataPath>

 

例如:

 

content://com.paad.provider.myapp/items

 

Content URI 可以表示爲兩種形式。上面的 URI 表示請求某類型的全部值(例如,所有項目)。

 

在其後追加 /<rownumber> ,如下所示,表示請求單一記錄(例如,第 5 個項目)。

 

content://com.paad.provider.myapp/items/5

 

支持這兩種方式來訪問你的 Provider 是個很好的形式。

 

做到這樣最簡單的方式是使用一個 UriMatcher 。當通過 ContentResolver 來訪問一個 Provider 時,配置 UriMatcher 解析 URI 來決定它們的形式。下面的代碼顯示了這一樣式的框架代碼:

 

public class MyProvider extends ContentProvider

{

private static final String myURI =“content://com.paad.provider.myapp/items”;

public static final Uri CONTENT_URI = Uri.parse(myURI);

 

@Override

public boolean onCreate()

{

// TODO: Construct the underlying database.

return true;

}

 

// Create the constants used to differentiate between the different

// URI requests.

private static final int ALLROWS = 1;

private static final int SINGLE_ROW = 2;

private static final UriMatcher uriMatcher;

// Populate the UriMatcher object, where a URI ending in ‘items’ will

// correspond to a request for all items, and ‘items/[rowID]’

// represents a single row.

static

{

uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

uriMatcher.addURI(“com.paad.provider.myApp”, “items”, ALLROWS);

uriMatcher.addURI(“com.paad.provider.myApp”, “items/#”,SINGLE_ROW);

}

}

你可以使用相同的技巧來暴露數據中不同子集的 URI 或數據庫中不同的表的 URI

 

一個好的習慣是:在 Provider 中保留列的名稱和索引,來簡化通過 Cursor 提取信息。

 

暴露數據源的訪問

 

你可以實現 delete insert update query 方法來暴露與你的 Content Provider 的查詢和交互功能。

 

這些方法作爲底層數據源的通用接口,允許 Android 應用程序跨越程序邊界來共享數據,而不需要爲每個程序公佈不同的接口。

 

最常見的場景是使用一個 Content Provider 來訪問一個私有的 SQLite 數據庫,但使用這些方法,你可以訪問任何數據源(包括文件或應用程序實例的變量)。

 

接下來的框架代碼顯示了一個 Content Provider 的查詢和交互功能。注意: UriMatcher 對象用於精煉交互和查詢請求。

 

@Override

public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sort)

{

// If this is a row query, limit the result set to the passed in row.

switch (uriMatcher.match(uri))

{

case SINGLE_ROW :

// TODO: Modify selection based on row id, where:

// rowNumber = uri.getPathSegments().get(1));

}

return null;

}

 

@Override

public Uri insert(Uri _uri, ContentValues _initialValues) {

long rowID = [ ... Add a new item ... ]

// Return a URI to the newly added item.

if (rowID > 0)

{

return ContentUris.withAppendedId(CONTENT_URI, rowID);

}

throw new SQLException(“Failed to add new item into “ + _uri);

}

 

@Override

public int delete(Uri uri, String where, String[] whereArgs)

{

switch (uriMatcher.match(uri))

{

case ALLROWS:

case SINGLE_ROW:

default: throw new IllegalArgumentException(“Unsupported URI:” + uri);

}

}

 

@Override

public int update(Uri uri, ContentValues values, String where,String[] whereArgs)

{

switch (uriMatcher.match(uri))

{

case ALLROWS:

case SINGLE_ROW:

default: throw new IllegalArgumentException(“Unsupported URI:” + uri);

}

}

 

創建 Content Provider 最後一步是定義標識 Provider 返回數據的 MIME 類型。

 

重寫 getType 方法,返回一個獨一無二的字符串來描述你的數據類型。返回的類型必須包含兩種形式,一種是單一項目,另一種是所有的項目,如下所示:

 

單一項目

vnd.<companyname>.cursor.item/<contenttype>

 

所有的項目

vnd.<companyName>.cursor.dir/<contenttype>

 

接下來的代碼片段顯示瞭如何重寫 getType 方法來一句傳入的 URI 來返回正確的 MIME 類型:

 

@Override

public String getType(Uri _uri)

{

switch (uriMatcher.match(_uri))

{

case ALLROWS: return “vnd.paad.cursor.dir/myprovidercontent”;

case SINGLE_ROW: return “vnd.paad.cursor.item/myprovidercontent”;

default: throw new IllegalArgumentException(“Unsupported URI: “ + _uri);

}

}

 

註冊 Provider

 

一旦完成了 Content Provider ,你必須將其添加到應用程序的 manifest 中。使用 authorities 標籤來指定它的路徑,如下面的 XML 片段所示:

 

<provider android:name=”MyProvider” android:authorities=”com.paad.provider.myapp”/>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章