(歡迎大家加入android技術交流QQ群:209796692)
實現ContentProvider類
ContentProvider 執行個體管理對一個結構型資料集的操作以處理從另外一個應用發來的請求。所有的操作最終都調用ContentResolver,然後它又調用ContentProvider 的一個具體的方法。
查詢方法們
虛類 ContentProvider 定義了六個虛方法,你必須在你的衍生類別中實現它們。這些方法們,除了 onCreate() ,都會被想要操作你的content provider的用戶端應用調用:
query()
從你的provider擷取資料。使用參數來指定要查詢的表,要返回行和列,和結果的排序方式。返回一個 Cursor 對象。
insert()
向你的provider插入一個新行。參數們指定了要選擇的表和要插入的列的值。返回一個指向新行的content URI。
update()
更新你的provider中已存在的行。參數中指定了要選擇的表和要更新的行以及要更新的列資料。返回更新的行的數量。
delete()
從你的provider中刪除行。參數們指定了要選擇是表和要刪除的行們。返回刪除打的行的數量。
getType()
返回對應一個content URI的MIME類型。
onCreate()
初始化你的provider。Android系統在建立你的provider之後立即調用此方法。注意你的Provider直到一個ContentResolver對象要操作它時才會被建立。
你要實現這些方法們,需要負責以上事情:
· 除了 onCreate() 所有的這些方法們都可以被多線程同時調用。所以你它們必須是多安全執行緒的。
· 避免在onCreate() 中進行耗時的操作。延遲初始化工作直到真正需要做的時候。
· 儘管你必須實現這些方法們,你的方法除了返回期望的資料類型外,並不是需要做所有的事情。例如,你可能想阻止其它應用向某些表中插入資料,你就可以不理會對insert() 的調用並返回0.
實現query()方法
ContentProvider.query() 方法必須返回一個 Cursor 對象,或者,如果它失敗了,拋出一個 Exception。如果你使用一個SQLite資料庫作你的資料存放區,你可以簡單的返回從 SQLiteDatabase 類的query() 方法返回的Cursor 對象。如果查詢不到任何行,你應該返回一個Cursor 的執行個體,但它的getCount() 方法返回0。你應該只在查詢過程中發生內部錯誤時才返回null。
如果你不用SQLite資料庫作為你的資料存放區,那麼需使用 Cursor的衍生類別。例如MatrixCursor 類,它實現了一個 cursor,cursor中的每一行都是一個Object的數組。這個類使用 addRow() 添加一個新行。
記住Android系統必須能跨進程傳送Exception 。Android可以為以下異常做這些。這些異常可能在處理查詢錯誤時有協助:
· IllegalArgumentException (如果你的provider收到一個不合法的content URI,你可以要拋出它)
· NullPointerException
實現insert()方法
insert() 方法向適當的表添加一個新行,使用的值都存放在參數ContentValues 中。如果一個列的名字不正合適 ContentValues 參數中,你可能要為此列提供一個預設的值,這可以在provider的代碼中做也可以在資料庫表中做。
此方法應返回新行的content URI。要構建此URI,使用withAppendedId()向表的content URI的後面添加新行的_ID (或其它的主鍵)的值即可。
實現delete()方法
delete() 方法不必在物理上從你的資料存放區中刪除行。如果你正在為你的provider用一種同步適配器,你應該考慮把一個要刪除的行打上"delete"標誌而不是把行整個刪除。同步適配器可以檢查要被刪除的行們並且在從provider中刪除它們之前從server刪除它們。
實現update() 方法
update() 方法帶有與insert()相同的參數類型ContentValues ,以及與delete() 和ContentProvider.query()相同的selection 和selectionArgs參數。這可能使你能在這些方法之間重用代碼。
實現onCreate() 方法
Android 系統在啟動provider後調用onCreate() 。你應該在此方法中只執行不耗時的初始化任務,並且延遲資料庫建立和資料載入工作,直到provider直正收到對資料的請求時再做。如果你在onCreate()中做了耗時的工作,你將減慢provider的啟動。相應的,這也會減緩從provider到其它應用的反應速度。
例如,如果你正在使用一個SQLite 資料庫,你可以在ContentProvider.onCreate()中建立一個新的SQLiteOpenHelper 對象,然後在第一次開啟資料庫時建立SQL的表們。為了協助你這樣做,第一次調用getWritableDatabase()時,它會自動調用SQLiteOpenHelper.onCreate()方法。
下面的兩個程式碼片段示範了在ContentProvider.onCreate() 和SQLiteOpenHelper.onCreate()之間的互動。第一段對ContentProvider.onCreate()的實現:
public class ExampleProvider extends ContentProvider /* * Defines a handle to the database helper object. The MainDatabaseHelper class is defined * in a following snippet. */ private MainDatabaseHelper mOpenHelper; // Defines the database name private static final String DBNAME = "mydb"; // Holds the database object private SQLiteDatabase db; public boolean onCreate() { /* * Creates a new helper object. This method always returns quickly. * Notice that the database itself isn't created or opened * until SQLiteOpenHelper.getWritableDatabase is called */ mOpenHelper = new SQLiteOpenHelper( getContext(), // the application context DBNAME, // the name of the database) null, // uses the default SQLite cursor 1 // the version number ); return true; } ... // Implements the provider's insert method public Cursor insert(Uri uri, ContentValues values) { // Insert code here to determine which table to open, handle error-checking, and so forth ... /* * Gets a writeable database. This will trigger its creation if it doesn't already exist. * */ db = mOpenHelper.getWritableDatabase(); }}
第二段代碼是對SQLiteOpenHelper.onCreate()的實現,包含了一個helper類:
...// A string that defines the SQL statement for creating a tableprivate static final String SQL_CREATE_MAIN = "CREATE TABLE " + "main " + // Table's name "(" + // The columns in the table " _ID INTEGER PRIMARY KEY, " + " WORD TEXT" " FREQUENCY INTEGER " + " LOCALE TEXT )";.../** * Helper class that actually creates and manages the provider's underlying data repository. */protected static final class MainDatabaseHelper extends SQLiteOpenHelper { /* * Instantiates an open helper for the provider's SQLite data repository * Do not do database creation and upgrade here. */ MainDatabaseHelper(Context context) { super(context, DBNAME, null, 1); } /* * Creates the data repository. This is called when the provider attempts to open the * repository and SQLite reports that it doesn't exist. */ public void onCreate(SQLiteDatabase db) { // Creates the main table db.execSQL(SQL_CREATE_MAIN); }}
歡迎大家加入android技術交流QQ群:209796692