日记本详解.docx

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

日记本详解.docx

《日记本详解.docx》由会员分享,可在线阅读,更多相关《日记本详解.docx(26页珍藏版)》请在冰点文库上搜索。

日记本详解.docx

日记本详解

8.5.3 使用ContentProvider操作数据日记本实例

(1)

在上一个例子当中学习了ContentProvider,并且使用了系统中的一个联系人的ContentProvider,在本节当中,我们仍然实现类似第8章所讲的日记本的例子,只不过这次我们用ContentProvider实现,而不是直接用数据库实现。

这样外界的程序就可以访问得到日记本这个应用数据。

通过这个例子可以学到。

如何实现一个ContentProvider。

理解UriMatcher的含义。

onPrepareOptionsMenu方法介绍。

具体实现步骤如下所示。

1.第一步

在Eclipse中打开ex09_2_contentProvider项目,具体操作步骤如下。

(1)新建一个项目,依次单击File→New→AndroidProject项。

(2)在新建项目的对话框中,选择Createprojectfromexistingsource项。

(3)单击浏览项,找到ex09_2_contentProvider项目,然后单击确定。

程序的目录结构如图8-31所示。

2.第二步

首先运行这个项目,将会看到如图8-32所示界面。

 

(点击查看大图)图8-31 程序的目录结构

 

(点击查看大图)图8-32 未添加任何数据的主界面

图8-32所示的这个界面我们在第8章的例子里已经见过。

本例的主Activity仍然是一个ListActivity,而且关联的布局文件也是diary_list.xml,关于ListActivity的使用方法和详细说明可以参见第7章第6节。

diary_list.xml的代码如下所示:

1.

xml version="1.0" encoding="utf-8"?

2.

Android="http:

//schemas.

3.Android:

layout_width="wrap_content" 

4.Android:

layout_height="wrap_content"> 

5. 

6.

id="@+id/Android:

list" 

7.Android:

layout_width="wrap_content" 

8.Android:

layout_height="wrap_content" /> 

9.

id="@+id/Android:

empty" 

10.Android:

layout_width="wrap_content" 

11.Android:

layout_height="wrap_content" Android:

text="

您还没有开始写日记呢!

单击下边的Menu按钮开始写日记吧:

)" /> 

12. 

代码解释:

其中ListView的id我们必须定义成Android:

id="@+id/Android:

list",这样系统才可以在ListActivity里引用的到。

3.第三步

和第8章的前一个日记本例子一样,日记本的数据还是存储在SQLite数据库中,但是不一样的是,在这个例子里,执行增、删、改、查操作时不是直接访问数据库,而是通过日记本程序的ContentProivder来实现。

我们先来看一下Diary这个类,这个类里边有一个内部静态类DiaryColumns,和它的名字意思一样,这个类里主要定义了日记本数据库的列表字段的名字,具体代码如下所示:

1.public static final class DiaryColumns implements BaseColumns { 

2.        private DiaryColumns() {} 

3.        public static final Uri CONTENT_URI = Uri.

parse("content:

//" + AUTHORITY + "/diaries"); 

4.        public static final String CONTENT_TYPE = 

"vnd.Android.cursor.dir/vnd.google. diary"; 

5.        public static final String CONTENT_ITEM_TYPE 

= "vnd.Android.cursor.item/vnd. google.diary"; 

6.        public static final String DEFAULT_SORT_ORDER = "created DESC"; 

7.        public static final String TITLE = "title"; 

8.        public static final String BODY = "body"; 

9.        public static final String CREATED = "created"; 

10.    } 

代码解释:

BaseColumns是一个接口,里边有两个变量,一个是_ID="_id",一个是_COUNT="_count"。

在Android当中,每一个数据库表至少有一个字段,而且这个字段是_id。

所以当我们构造列名的辅助类时,直接实现BaseColumns,这样我们便默认地拥有了_id字段。

在我们的日记本的数据表里,一共有4个字段,分别是:

"id"、"title"、"body"、"created"。

小知识 在Android的设计"哲学"里是鼓励开发者使用内部类的,这样不但使用方便,而且执行效率也高。

8.5.3 使用ContentProvider操作数据日记本实例

(2)

4.第四步

现在我们来看DiaryContentProvider类,这个类继承自ContentProvider,在这个类里边实现了ContentProvider的一些接口方法,并且成为日记本的一个ContentProvider。

我们现在通过学习这个类,来详细了解实现一个自定义的ContentProvider的具体步骤。

(1)继承ContentProvider.DiaryContentProvider类是继承ContentProvider类的。

(2)定义一个publicstaticfinal的Uri类型的变量,并且命名为CONTENT_URI。

DiaryContentProvider所能处理的Uri都是基于CONTENT_URI来构建的,需要注意的是,这个CONTENT_URI中的内容以content:

//开头,并且全部小写,且全局惟一。

下边是在这个例子中的一个普通URI,通过分析这个URI,可以了解contentURI的构成,代码如下所示:

content:

//com.ex09_2_contentprovider.diarycontentprovider/diaries/1

代码解释:

第一部分是content:

//,这部分是一直存在的,也是不用做什么修改的。

第二部分是授权(AUTHORITY)部分,在这个例子里边就是com.ex09_2_contentprovider.diarycontentprovider,授权部分是惟一的,在程序中一般是我们实现的那个ContentProvider的全称,并且全都小写。

这部分是和在AndroidManifest.xml文件当中的

name="DiaryContentProvider

Android:

authorities="com.ex09_2_contentprovider.diarycontentprovider"/>部分对应的。

第三部分是请求数据的类型,例如,在这个例子当中定义的类型是diaries。

当然这一部分可以是0个片段或者多个片段构成,如果ContentProvider只是暴露出了一种类型的数据,那么这部分可以为空,但是如果暴露出了多种,尤其是包含子类的时候,就不能为空,例如,日记本程序里边可以暴露出来两种数据,一种是用户自己的"diaries/my",另一种是其他人的"diaries/others"。

第四部分就是"1",当然这部分是允许为空的。

如果为空,表示请求全部数据;如果不为空,表示请求特定ID的数据。

(3)构建用户的数据存储系统。

在这个例子当中,是将数据存储到数据库系统当中。

通常是将数据存储在数据库系统中,但是也可以将数据存储在其他的地方,如文件系统等。

(4)实现ContentProvider这个抽象类的抽象方法,具体如下所示:

publicbooleanonCreate(),当ContentProvider生成的时候调用此方法。

publicCursorquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder),此方法返回一个Cursor对象作为查询结果集。

publicUriinsert(Uriuri,ContentValuesinitialValues),此方法负责往数据集当中插入一列,并返回这一列的Uri。

publicintdelete(Uriuri,Stringwhere,String[]whereArgs),此方法负责删除指定Uri的数据。

publicintupdate(Uriuri,ContentValuesvalues,Stringwhere,String[]whereArgs),此方法负责更新指定Uri的数据。

publicStringgetType(Uriuri),返回所给Uri的MIME类型。

(5)在AndroidManifest.xml文件中增加标签,例如,在这个例子中,实现的代码为:

name="DiaryContentProvider"Android:

authorities="com.ex09_2_contentprovider.diarycontentprovider"/>,其中Android:

name为我们实现的这个contentprovider的类名;Android:

authorities为contentURI的第二部分,即授权部分,代码为:

"com.ex09_2_contentprovider.diarycontentprovider"。

5.第五步

继续来看DiaryContentProvider类的代码。

此实例的数据是存储在数据库当中,和前面章节学过的数据例子一样,此实例中我们定义了DatabaseHelper辅助类。

这个类在第8章中有详细的讲解,这里就不再进行详细说明,具体代码如下所示:

1.private static class DatabaseHelper extends SQLiteOpenHelper { 

2. 

3.DatabaseHelper(Context context) { 

4.super(context, DATABASE_NAME, null, DATABASE_VERSION); 

5.} 

6. 

7.@Override 

8.public void onCreate(SQLiteDatabase db) { 

9.db.execSQL("CREATE TABLE " + DIARY_TABLE_NAME + " (" 

10.+ DiaryColumns._ID + " INTEGER PRIMARY KEY," 

11.+ DiaryColumns.TITLE + " TEXT," + DiaryColumns.BODY 

12.+ " TEXT," + DiaryColumns.CREATED + " TEXT" + ");"); 

13.} 

14. 

15.@Override 

16.public void onUpgrade(SQLiteDatabase db, int 

oldVersion, int newVersion) { 

17.db.execSQL("DROP TABLE IF EXISTS notes"); 

18.onCreate(db); 

19.} 

20.} 

代码解释:

DatabaseHelper里操作数据库的辅助类,通过这个类我们可以生成数据库,并且维护这个数据库。

在DiaryContentProvider中,我们定义了一些变量和常量,其中这些常量主要是描述数据库的信息。

1.private static final String DATABASE_NAME = "database"; 

2.private static final int DATABASE_VERSION = 1; 

3.private static final String DIARY_TABLE_NAME = "diary"; 

4. 

5.private static HashMap sDiariesProjectionMap; 

6. 

7.private static final int DIARIES = 1; 

8.private static final int DIARY_ID = 2; 

9. 

10.private static final UriMatcher sUriMatcher; 

小知识 什么是UriMatcher?

UriMatcher是匹配Uri的一个辅助类,例如,在我们的DiaryContentProvider中的static模块中,有下边的代码:

sUriMatcher=newUriMatcher(UriMatcher.NO_MATCH);

sUriMatcher.addURI(Diary.AUTHORITY,"diaries",DIARIES);

sUriMatcher.addURI(Diary.AUTHORITY,"diaries/#",DIARY_ID);

代码解释:

sUriMatcher.addURI(Diary.AUTHORITY,"diaries",sUriMatcher.match(uri))表示,如果我们的Uri是content:

//com.ex09_2_contentprovider.diarycontentprovider/diaries/,那么sUriMatcher.match(uri)的返回值就是DIARIES。

sUriMatcher.addURI(Diary.AUTHORITY,"diaries/#",DIARY_ID)表示,如果我们的Uri是content:

//com.ex09_2_contentprovider.diarycontentprovider/diaries/id(其中后边的id是一个数字),那么sUriMatcher.match(uri)的返回值就是DIARY_ID。

通过UriMatcher类我们可以很方便地判断一个Uri的类型,特别是判断这个Uri是对单个数据的请求,还是对全部数据的请求。

8.5.3 使用ContentProvider操作数据日记本实例(3)

6.第六步

现在我们来看一下在第四步列出来的抽象方法具体是怎么实现的。

我们就从增、删、改、查的顺序说起。

(1)首先来看插入的方法:

insert()。

具体实现代码如下所示:

1.@Override 

2.public Uri insert(Uri uri, ContentValues initialValues) { 

3.if (sUriMatcher.match(uri) !

= DIARIES) { 

4.throw new IllegalArgumentException("Unknown URI " + uri); 

5.} 

6. 

7.ContentValues values; 

8.if (initialValues !

= null) { 

9.values = new ContentValues(initialValues); 

10.} else { 

11.values = new ContentValues(); 

12.} 

13. 

14.if (values.containsKey(Diary.DiaryColumns.CREATED) == false) { 

15.values.put(Diary.DiaryColumns.CREATED, getFormateCreatedDate()); 

16.} 

17. 

18.if (values.containsKey(Diary.DiaryColumns.TITLE) == false) { 

19.Resources r = Resources.getSystem(); 

20.values.put(Diary.DiaryColumns.TITLE, r 

21..getString(Android.R.string.untitled)); 

22.} 

23. 

24.if (values.containsKey(Diary.DiaryColumns.BODY) == false) { 

25.values.put(Diary.DiaryColumns.BODY, ""); 

26.} 

27. 

28.SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 

29.long rowId = db.insert(DIARY_TABLE_NAME, DiaryColumns.BODY, values); 

30.if (rowId > 0) { 

31.Uri diaryUri= ContentUris.withAppendedId( 

32.Diary.DiaryColumns.CONTENT_URI, rowId); 

33.return diaryUri; 

34.} 

35. 

36.throw new SQLException("Failed to insert row into " + uri); 

37.} 

代码解释:

首先我们通过语句sUriMatcher.match(uri)!

=DIARIES对传进来的Uri进行了判断,如果这个Uri不是DIARIES类型的,那么这个Uri就是一个非法的Uri。

SQLiteDatabasedb=mOpenHelper.getWritableDatabase()语句负责得到一个SQLiteDatabase的实例。

db.insert(DIARY_TABLE_NAME,DiaryColumns.BODY,values)语句负责插入一条记录到数据库中。

需要注意的是,insert()返回的是一个Uri,而不是一个记录的id,所以,我们还应该把记录的id构造成一个Uri:

UridiaryUri=ContentUris.withAppendedId(Diary.DiaryColumns.CONTENT_URI,rowId).withAppendedId()方法在下边的小知识当中详细介绍。

小知识 什么是ContentUris?

ContentUris是contentURI的一个辅助类。

它有两个方法很有用,具体如下所示。

publicstaticUriwithAppendedId(UricontentUri,longid),这个方法负责把id和contentUri连接成一个新的Uri。

比如在我们这个例子当中是这么使用的:

ContentUris.withAppendedId(Diary.DiaryColumns.CONTENT_URI,rowId)。

如果rowId为100的话,那么现在的这个Uri的内容就是:

content:

//com.ex09_2_contentprovider.diarycontentprovider/diaries/100。

publicstaticlongparseId(UricontentUri),这个方法负责把contentURI后边的id解析出来,比如现在这个contentURI是content:

//com.ex09_2_contentprovider.diarycontentprovider/diaries/100,那么这个函数的返回值就是100。

(2)现在来看删除方法:

delete()。

具体实现代码如下所示:

1.@Override 

2.public int delete(Uri uri, String where, String[] whereArgs) { 

3.SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 

4.String rowId = uri.getPathSegments().get

(1); 

5.return db .delete(DIARY_TABLE_NAME, DiaryColumns._ID + "=" + rowId, null); 

6.} 

代码解释:

rowId=uri.getPathSegments().get

(1)负责得到rowId的值。

getPathSegments()方法得到一个String的List,在我们例子当中uri.getPathSegments().get

(1)为rowId,如果是uri.getPathSegments().get(0)那值就为"diaries"。

db.delete(DIARY_TABLE_NAME,DiaryColumns._ID+"="+rowId,null)是标准的SQLite删除操作。

第一个参数数据表的名字,第二个参数相当于SQL语句当中的where部分。

(3)更新一条数据的方法:

update()。

具体实现代码如下所示:

1.@Override 

2.public int update(Uri uri, ContentValues values, String where, 

3.String[] whereArgs) { 

4.SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 

5.String rowId = uri.getPathSegments().get

(1); 

6.return db.update(DIARY_TABLE_NAME, values, DiaryColumns._ID + "=" 

7.+ rowId

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

当前位置:首页 > 求职职场 > 简历

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

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