content providerexample.docx

上传人:b****2 文档编号:2253257 上传时间:2023-05-03 格式:DOCX 页数:56 大小:44.93KB
下载 相关 举报
content providerexample.docx_第1页
第1页 / 共56页
content providerexample.docx_第2页
第2页 / 共56页
content providerexample.docx_第3页
第3页 / 共56页
content providerexample.docx_第4页
第4页 / 共56页
content providerexample.docx_第5页
第5页 / 共56页
content providerexample.docx_第6页
第6页 / 共56页
content providerexample.docx_第7页
第7页 / 共56页
content providerexample.docx_第8页
第8页 / 共56页
content providerexample.docx_第9页
第9页 / 共56页
content providerexample.docx_第10页
第10页 / 共56页
content providerexample.docx_第11页
第11页 / 共56页
content providerexample.docx_第12页
第12页 / 共56页
content providerexample.docx_第13页
第13页 / 共56页
content providerexample.docx_第14页
第14页 / 共56页
content providerexample.docx_第15页
第15页 / 共56页
content providerexample.docx_第16页
第16页 / 共56页
content providerexample.docx_第17页
第17页 / 共56页
content providerexample.docx_第18页
第18页 / 共56页
content providerexample.docx_第19页
第19页 / 共56页
content providerexample.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

content providerexample.docx

《content providerexample.docx》由会员分享,可在线阅读,更多相关《content providerexample.docx(56页珍藏版)》请在冰点文库上搜索。

content providerexample.docx

contentproviderexample

上文简要介绍了Android应用程序组件ContentProvider在应用程序间共享数据的原理,但是没有进一步研究它的实现。

本文将实现两个应用程序,其中一个以ContentProvider的形式来提供数据访问入口,另一个通过这个ContentProvider来访问这些数据。

本文的例子不仅可以为下文分析ContentProvider的实现原理准备好使用情景,还可以学习到它的一个未公开接口。

     本文中的应用程序是按照上一篇文章Android应用程序组件ContentProvider简要介绍和学习计划中提到的一般应用程序架构方法来设计的。

本文包含两个应用程序,其中,第一个应用程序命名为ArticlesProvider,它使用了SQLite数据库来维护一个文章信息列表,同时,它定义了访问这个文章信息列表的URI,这样,我们就可以通过一个ContentProvider组件来向第三方应用程序提供访问这个文章信息列表的接口;第二个应用程序命名为Article,它提供了管理保存在ArticlesProvider应用程序中的文章信息的界面入口,在这个应用程序中,用户可以添加、删除和修改这些文章信息。

接下来我们就分别介绍这两个应用程序的实现。

     1.ArticlesProvider应用程序的实现

     首先是参照在Ubuntu上为Android系统内置Java应用程序测试ApplicationFrameworks层的硬件服务一文,在packages/experimental目录下建立工程文件目录ArticlesProvider。

在继续介绍这个应用程序的实现之前,我们先介绍一下这个应用程序用来保存文章信息的数据库的设计。

     我们知道,在Android系统中,内置了一款轻型的数据库SQLite。

SQLite是专门为嵌入式产品而设计的,它具有占用资源低的特点,而且是开源的,非常适合在Android平台中使用,关于SQLite的更多信息可以访问官方网站http:

//www.sqlite.org。

      ArticlesProvider应用程序就是使用SQLite来作为数据库保存文章信息的,数据库文件命名为Articles.db,它里面只有一张表ArticlesTable,表的结构如下所示:

     -------------------------------------------------------------

     | -- _id -- | -- _title -- | -- _abstrat -- | -- _url -- |

     -------------------------------------------------------------

     |       |          |            |         | 

     它由四个字段表示,第一个字段_id表示文章的ID,类型为自动递增的integer,它作为表的key值;第二个字段_title表示文章的题目,类型为text;第三个字段_abstract表示文章的摘要,类型为text;第四个字段_url表示文章的URL,类型为text。

注意,当我们打算将数据库表的某一列的数据作为一个数据行的ID时,就约定它的列名为_id。

这是因为我们经常需要从数据库中获取一批数据,这些数据以Cursor的形式返回,对这些返回来的数据我们一般用一个ListView来显示,而这个ListView需要一个数据适配器Adapter来作为数据源,这时候就我们就可以以这个Cursor来构造一个Adapter。

有些Adapter,例如android.widget.CursorAdapter,它们在实现自己的getItemId成员函数来获取指定数据行的ID时,就必须要从这个Cursor中相应的行里面取出列名为_id的字段的内容出来作为这个数据行的ID返回给调用者。

当然,我们不在数据库表中定义这个_id列名也是可以的,不过这样从数据库中查询数据后得到的Cursor适合性就变差了,因此,建议我们在设计数据库表时,尽量设置其中一个列名字_id,并且保证这一列的内容是在数据库表中是唯一的。

     下面我们就开始介绍这个应用程序的实现了。

这个应用程序只有两个源文件,分别是Articles.java和ArticlesProvider,都是放在shy.luo.providers.articles这个package下面。

在Articles.java文件里面,主要是定义了一些常量,例如用来访问文章信息数据的URI、MIME(MultipurposeInternetMailExtensions)类型以及格式等,这些常量是第三方应用程序访问这些文章信息数据时要使用到的,因此,我们把它定义在一个单独的文件中,稍后我们会介绍如果把这个Articles.java文件打包成一个jar文件,然后第三方应用程序就可以引用这个常量了,这样也避免了直接把这个源代码文件暴露给第三方应用程序。

     源文件Articles.java位于src/shy/luo/providers/articles目录下,它的内容如下所示:

[java] viewplaincopy

1.package shy.luo.providers.articles;  

2.  

3.import .Uri;  

4.  

5.public class Articles {  

6.        /*Data Field*/  

7.        public static final String ID = "_id";  

8.        public static final String TITLE = "_title";  

9.        public static final String ABSTRACT = "_abstract";  

10.        public static final String URL = "_url";  

11.  

12.        /*Default sort order*/  

13.        public static final String DEFAULT_SORT_ORDER = "_id asc";  

14.  

15.        /*Call Method*/  

16.        public static final String METHOD_GET_ITEM_COUNT = "METHOD_GET_ITEM_COUNT";  

17.        public static final String KEY_ITEM_COUNT = "KEY_ITEM_COUNT";  

18.  

19.        /*Authority*/  

20.        public static final String AUTHORITY = "shy.luo.providers.articles";  

21.  

22.        /*Match Code*/  

23.        public static final int ITEM = 1;  

24.        public static final int ITEM_ID = 2;  

25.        public static final int ITEM_POS = 3;  

26.  

27.        /*MIME*/  

28.        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.shy.luo.article";  

29.        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.shy.luo.article";  

30.  

31.        /*Content URI*/  

32.        public static final Uri CONTENT_URI = Uri.parse("content:

//" + AUTHORITY + "/item");  

33.        public static final Uri CONTENT_POS_URI = Uri.parse("content:

//" + AUTHORITY + "/pos");  

34.}  

     ID、TITLE、ABSTRACT和URL四个常量前面已经解释过了,它是我们用来保存文章信息的数据表的四个列名;DEFAULT_SORT_ORDER常量是调用ContentProvider接口的query函数来查询数据时用的,它表示对查询结果按照_id列的值从小到大排列;METHOD_GET_ITEM_COUNT和KEY_ITEM_COUNT两个常量是调用ContentProvider接口的一个未公开函数call来查询数据时用的,它类似于微软COM中的IDispatch接口的Invoke函数,使用这个call函数时,传入参数METHOD_GET_ITEM_COUNT表示我们要调用我们自定义的ContentProvider子类中的getItemCount函数来获取数据库中的文章信息条目的数量,结果放在一个Bundle中以KEY_ITEM_COUNT为关键字的域中。

     剩下的常量都是跟数据URI相关的,这个需要详细解释一下。

URI的全称是UniversalResourceIdentifier,即通用资源标志符,通过它用来唯一标志某个资源在网络中的位置,它的结构和我们常见的HTTP形式URL是一样的,其实我们可以把常见的HTTP形式的URL看成是URI结构的一个实例,URI是在更高一个层次上的抽象。

在Android系统中,它也定义了自己的用来定痊某个特定的ContentProvider的URI结构,它通常由四个组件来组成,如下所示:

     [content:

//][shy.luo.providers.articles][/item][/123]

     |------A------|-----------------B-------------------|---C---|---D--|

     A组件称为Scheme,它固定为content:

//,表示它后面的路径所表示的资源是由ContentProvider来提供的。

     B组件称为Authority,它唯一地标识了一个特定的ContentProvider,因此,这部分内容一般使用ContentProvider所在的package来命名,使得它是唯一的。

     C组件称为资源路径,它表示所请求的资源的类型,这部分内容是可选的。

如果我们自己所实现的ContentProvider只提供一种类型的资源访问,那么这部分内部就可以忽略;如果我们自己实现的ContentProvider同时提供了多种类型的资源访问,那么这部分内容就不可以忽略了。

例如,我们有两种电脑资源可以提供给用户访问,一种是笔记本电脑,一种是平板电脑,我们就把分别它们定义为notebook和pad;如果我们想进一步按照系统类型来进一步细分这两种电脑资源,对笔记本电脑来说,一种是安装了windows系统的,一种是安装了linux系统的,我们就分别把它们定义为notebook/windows和notebook/linux;对平板电脑来说,一种是安装了ios系统的,一种是安装了android系统的,我们就分别把它们定义为pad/ios和pad/android。

     D组件称为资源ID,它表示所请求的是一个特定的资源,它通常是一个数字,对应前面我们所介绍的数据库表中的_id字段的内容,它唯一地标志了某一种资源下的一个特定的实例。

继续以前面的电脑资源为例,如果我们请求的是编号为123的装了android系统的平板电脑,我们就把它定义为pad/android/123。

当忽略这部分内容时,它有可能是表示请求某一种资源下的所有实例,取决于我们的URI匹配规则,后面我们将会进一步解释如何设置URI匹配规则。

     回到上面的Articles.java源文件中,我们定义了两个URI,分别用COTENT_URI和CONTENT_POS_URI两个常量来表示,它们的Authority组件均指定为shy.luo.providers.articles。

其中,COTENT_URI常量表示的URI表示是通过ID来访问文章信息的,而CONTENT_POS_URI常量表示的URI表示是通过位置来访问文章信息的。

例如,content:

//shy.luo.providers.articles/item表示访问所有的文章信息条目;content:

//shy.luo.providers.articles/item/123表示只访问ID值为123的文章信息条目;content:

//shy.luo.providers.articles/pos/1表示访问数据库表中的第1条文章信息条目,这条文章信息条目的ID值不一定为1。

通过常量CONTENT_POS_URI来访问文章信息条目时,必须要指定位置,这也是我们设置的URI匹配规则来指定的,后面我们将会看到。

     此外,我们还需要定义与URI对应的资源的MIME类型。

每个MIME类型由两部分组成,前面是数据的大类别,后面定义具体的种类。

在ContentProvider中,URI所对应的资源的MIME类型的大类别根据同时访问的资源的数量分为两种,对于访问单个资源的URI,它的大类别就为vnd.android.cursor.item,而对于同时访问多个资源的URI,它的大类别就为vnd.android.cursor.dir。

ContentProvider的URI所对应的资源的MIME类型的具体类别就需要由ContentProvider的提供者来设置了,它的格式一般为vnd.[companyname].[resourcetype]的形式。

例如,在我们的例子中,CONTENT_TYPE和COTENT_ITEM_TYPE两个常量分别定义了两种MIME类型,它们的大类别分别为vnd.android.cursor.dir和vnd.android.cursor.item,而具体类别均为vdn.shy.luo.article,其中shy.luo就是表示公司名了,而article表示资源的类型为文章。

这两个MIME类型常量主要是在实现ContentProvider的getType函数时用到的,后面我们将会看到。

     最后,ITEM、ITEM_ID和POS_ID三个常量分别定了三个URI匹配规则的匹配码。

如果URI的形式为content:

//shy.luo.providers.articles/item,则匹配规则返回的匹配码为ITEM;如果URI的形式为content:

//shy.luo.providers.articles/item/#,其中#表示任意一个数字,则匹配规则返回的匹配码为ITEM_ID;如果URI的形式为#也是表示任意一个数字,则匹配规则返回的匹配码为ITEM_POS。

这三个常量的用法我们在后面也将会看到。

     这样,Articles.java文件的内容就介绍完了。

下面我们再接着介绍位于src/shy/luo/providers/articles目录下的ArticlesProvider.java文件,它的内容如下所示:

[java] viewplaincopy

1.import java.util.HashMap;  

2.  

3.import android.content.ContentValues;  

4.import android.content.Context;  

5.import android.content.UriMatcher;  

6.import android.content.ContentProvider;  

7.import android.content.ContentUris;  

8.import android.content.ContentResolver;  

9.import android.database.Cursor;  

10.import android.database.sqlite.SQLiteDatabase;  

11.import android.database.sqlite.SQLiteDatabase.CursorFactory;  

12.import android.database.sqlite.SQLiteException;  

13.import android.database.sqlite.SQLiteOpenHelper;  

14.import android.database.sqlite.SQLiteQueryBuilder;  

15.import .Uri;  

16.import android.os.Bundle;  

17.import android.text.TextUtils;  

18.import android.util.Log;  

19.  

20.public class ArticlesProvider extends ContentProvider {  

21.        private static final String LOG_TAG = "shy.luo.providers.articles.ArticlesProvider";  

22.  

23.        private static final String DB_NAME = "Articles.db";  

24.        private static final String DB_TABLE = "ArticlesTable";  

25.        private static final int DB_VERSION = 1;  

26.  

27.        private static final String DB_CREATE = "create table " + DB_TABLE +  

28.                                " (" + Articles.ID + " integer primary key autoincrement, " +  

29.                                Articles.TITLE + " text not null, " +  

30.                                Articles.ABSTRACT + " text not null, " +  

31.                                Articles.URL + " text not null);";  

32.  

33.        private static final UriMatcher uriMatcher;  

34.        static {  

35.                uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);  

36.                uriMatcher.addURI(Articles.AUTHORITY, "item", Articles.ITEM);  

37.                uriMatcher.addURI(Articles.AUTHORITY, "item/#", Articles.ITEM_ID);  

38.                uriMatcher.addURI(Articles.AUTHORITY, "pos/#", Articles.ITEM_POS);  

39.        }  

40.  

41.        private static final HashMap articleProjectionMap;  

42.        static {  

43.                articleProjectionMap = new HashMap();  

44.                articleProjectionMap.put(Articles.ID, Articles.ID);  

45.                articleProjectionMap.put(Articles.TITLE, Articles.TITLE);  

46.                articleProjectionMap.put(Articles.ABSTRACT, Articles.ABSTRACT);  

47.                articleProjectionMap.put(Articles.URL, Articles.URL);  

48.        }  

49.  

50.        private DBHelper dbHelper = null;  

51.        private ContentResolver resolver = null;  

52.  

53.        @Override  

54.        public boolean onCreate() {  

55.                Context context = getContext();  

56.                resolver = context.getContentResolver();  

57.                dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION);  

58.  

59.                Log.i(LOG_TAG, "Articles Provider Create");  

60.  

61.                return true;  

62.        }  

63.  

64.        @Override  

65.        public String g

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2