如何创建自己的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”/>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值