3.5.2 数据源组件的开发

开发一个数据源组件,需要从android.content.ContentProvider类派生,并实现其中的抽象方法,同时需要在配置文件中描述其URI等信息,一个简单示例如下:


//子类com.duguhome.test.SimpleContentProvider

public class SimpleContentProvider extends ContentProvider{

@Override

public void onCreate(){

//构造组件时调用,通常会做初始化数据的工作,比如:创建数据库

}

@Override

public int delete(Uri uri, String selection, String[]selectionArgs){

//执行删除数据,返回删除条数

}

@Override

public Uri insert(Uri uri, ContentValues values){

//实现插入数据,返回新添加数据URI的地址信息

}

@Override

public int update(Uri uri, ContentValues values, String selection, String[]

selectionArgs){

//实现更新数据,返回更新了的条数

}

@Override

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

selectionArgs, String sortOrder){

//实现查询数据,返回相关数据集的指针对象

}

@Override

public String getType(Uri uri){

//查询URI指向数据的类型,返回它的MIME类型,如果是列表类型,形如:vnd.android.cursor.

dir/,如果是单个数据,形如:vnd.android.cursor.item/

}

}

//在配置文件中添加组件信息,与一般组件不同,authorities信息是必需的

<application…>

<provider android:name="SimpleContentProvider"

android:authorities="com.duguhome.provider.sample">

</provider>

</application>


与其他组件不同,数据源组件的主要目标是提供数据而不是功能,它采用的是URI配合SQL的使用模式,而没有使用Android的意图机制。这就使得它成为与调用者耦合最大的组件。调用组件需要了解数据源的很多相关信息,比如:数据源组件的URI是什么、它支持哪些操作、它有哪些数据项(对应数据库的列)。因此,在开发数据源组件时,通常需要将数据源的地址、列、排序方式等信息封装成类,提供给使用者,示例如下:


public class SimpleProviderInfo{

//定义数据源的Authority信息

public static final String AUTHORITY=

"com.duguhome.provider.sample";

//定义调用者需要使用的URI信息

public static final Uri AUTHORITY_URI=Uri.parse(

"content://"+AUTHORITY);

//…定义更多相关的URI

//定义数据列名,BaseColumns接口中定义了id列和count信息

public static class ItemColumns implements BaseColumns{

//定义名字列

public static final String NAME="name";

//…其他各列也按照类似方式定义

}

//定义更多类似的Column类

}


数据源组件和其他组件一样,都构造于应用主线程中。直接对它进行数据的读写操作可能会阻塞主线程,从而影响应用与用户的交互。因此,当涉及大量的读写和查询时,调用者可以通过android.content.AsyncQueryHandler对象来实现对数据源组件的异步访问。如图3-15所示,每个AsyncQueryHandler对象都会开启一个后台线程,在线程中执行与数据源组件的数据交互,进行数据增、删、改、查操作。

3.5.2 数据源组件的开发 - 图1

图 3-15 Android数据源组件的异步使用

调用时,可以通过AsyncQueryHandler.startXXX系列方法将请求打包发送到后台线程,当相关处理完成后,会将结果异步回传给主线程并调用AsyncQueryHandler.onXXXComplete方法通知调用者。调用者在每次请求时,需要传入一个整型值token作为这次请求的标识,当该请求完成后进行回调时,会将token传回,帮助调用者确定这是哪一次请求。