Android 内容提供器---创建内容提供器(实现ContentProvider类)

ContentProvider对象实例通过处理来之其他应用程序的请求来管理对结构化数据集的访问。最终调用ContentResolver对象的所有的访问形式,都会对应ContentProvider类的具体方法。

必要的方法

抽象类ContentProvider定义了六个抽象方法,你必须在你自己具体的子类中来实现这些方法。这些方法中除了onCreate()以外,都用于视图访问你的内容提供的客户端应用程序调用。

query()

从提供器中获取数据,使用参数对选择的表进行查询,返回行和列的值,并且对结果进行排序。以Cursor对象的形式返回的数据。

insert()

把一行新的数据插入到提供器中。使用参数来选择目的表并获得参数中要使用的列值。返回最新插入的行的内容资源标识。

update()

更新提供器中既存的行。使用参数来选择要更新表和行,并获得被更新的列的值。返回被更新的行数。

delete()

从提供器中删除行。使用参数来选择要删除的表和行,返回被删除的行数。

getType()

返回对应的内容资源标识的MIME类型。

onCreate()

初始化提供器,在系统创建提供器之后会立即调用这个方法。注意直到ContentResolver对象试着访问提供器时,这个提供器才被创建。

注意这些方法有与ContentResolver完全相同的方法签名。

实现这方法时应该考虑以下事情:

1. 所有的这些方法除了onCreate()以外,都能够同时被多线程调用,因此它们必须是线程安全的。有关多线程的学习,请看“进程和线程”。

2. 避免在onCreate()方法中做长时操作。直到实际需要的时候才初始化任务。有关原因会在“实现onCreate()方法”章节中进行更多的讨论。

3. 尽管你必须实现这些方法,但是你的代码除了返回预定的数据类型之外,不做任何事情。例如,你可能会想阻止其他应用程序把数据插入到某些表中,你能够通过这种方法忽略对insert()方法的调用,并且返回“0”。

实现query()方法

ContentProvider.query()方法必须返回一个Cursor对象,如果执行失败,就抛出一个异常。如果你正在使用一个SQLite数据库做为你的数据存储,你能够通过调用SQLiteDatabase类的一个query()方法,就能简单的返回Cursor对象。如果查询不到匹配的行,那么返回的Cursor对象的getCount()方法就会返回0。只有在查询过程期间发生了内部错误,你才应该返回null。

如果你不适用SQLite数据库做为数据存储,那么就要使用Cursor的一个具体子类。如,MatrixCursor类实现了每行是一个对象数组的游标,这个类用addRow()方法来添加新行。

记住,Android系统必须能够跨进程来传递异常。在处理的查询错误中,下列异常可用于进程间传递:

1. IllegalArgumentException(如果提供器收到一个无效的内容资源标识,可以选择抛出这个异常)

2. NullPointerException

实现insert()方法

insert()方法使用ContentValues参数中的值把一行新的数据添加到相应的表中。如果在ContentValues参数中没有列名,你可能是想要使用提供器代码或数据库模式来提供默认值。

这个方法应该返回新插入行的内容资源标识。使用withAppendedId()方法给这个新行追加一个_ID(或其他主键)值。

实现delete()方法

不要使用delete()方法从你的数据存储中物理的删除行。因为如果你的提供器使用了同步适配器,你就应该使用“delete”标识来标记要删除的行,而不是把完全的删除行。同步适配器会在从提供器中删除它们之前检查要删除的行,并且从服务端删除它们。

实现update()方法

Update()方法需要与insert()方法使用的相同的ContentValues参数,以及与delete()方法和query()方法相同的selection和selectionArgs参数。这种方法允许你在这些方法之间重用代码。

实现onCreate()方法

Android系统会在提供器启动时调用onCreate()方法。你只应该在这个方法中执行快速的初始任务,并且要把数据库的创建和数据的装载延迟到提供器接收到实际的数据请求之后。如果在你onCreate()方法中你执行了长时任务,会降低提供器的启动速度,从而降低提供器对其他应用程序的响应速度。

例如,如果你使用SQLite数据库,而且在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()方法的实现,而且包括了一个助手类:

...
// A string that defines the SQL statement for creating a table
private 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 内容提供器---创建内容提供器(实现ContentProvider类))