热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android组件exc,Android中的四大组件之一:内容提供者

1.1.什么是内容提供者内容提供者是Android中的四大组件之一,可以将应用中的数据对外进行共享内容提供者将数据的访问方式统一,不必针对不同数据类型采

1.1. 什么是内容提供者

内容提供者是Android中的四大组件之一,可以将应用中的数据对外进行共享

内容提供者将数据的访问方式统一,不必针对不同数据类型采取不同的访问策略

内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据

内容提供者中数据更改可被监听

1.2. 创建内容提供者

定义类继承ContentProvider,根据需要重写内部方法

在清单文件的节点下进行配置,标签中需要指定name和authorities属性

name为类名,包名从程序Package开始,以“.”开始

authorities:是访问Provider时的路径,要唯一

URI代表要操作的数据,由scheme、authorites、path三部分组成

content://cn.itcast.provider.itcast/person

scheme:固定为content,代表访问内容提供者

authorites:节点中的authorites属性

path:程序定义的路径,可根据业务逻辑定义

在以下情况下你需要使用Content Providers:

1.你想为其他应用程序提供复杂数据或文件;

2.你想允许用户从你的应用程序中拷贝复杂数据到其他的应用中

3.你想使用搜索框架提供自定义的查询建议功能

Content

Provider通过URI(统一资源定位符)来访问数据,URI可以理解为访问数据的唯一地址,URI由authority和数据地址构成,关于authority可以理解成网站地址中的主机地址,而数据地址可以理解成某一个页面的子地址,二者共同构成了一个完整的访问地址,关于authority的命名,官方文档中有这么一句话

If your Android package name iscom.example., you should give your

provider the authority

com.example..provider.可见对于authority的命名还是有一定的规范性的。

关于URI的格式:content:,path就是数据路径,比如说一张表,而id就是这张表中主键为id的一行,也可以理解成一个实体对象。

1.Content Providers是Android系统中四大组件之一,提供一套在客户端(client)和数据源(data

source)之间的访问接口

2.Content Providers可以提供跨进程访问数据的功能,能暴露本地数据给其他应用访问

3.实现Content

Providers只需要继承抽象类ContentProvider并实现必要的抽象方法即可,访问ContentProvider则根据URI来访问

1.3. 完成CRUD方法

Ÿ 当程序调用CRUD方法时会传入Uri

Ÿ 我们通过Uri判断调用者要操作的数据

可以使用工具类UriMatcher来判断Uri

addURI方法可以添加Uri

match方法可以匹配一个Uri判断其类型

Ÿ 根据业务逻辑操作数据

1.4. 完成getType方法

Ÿ 如果返回数据是单条数据:vnd.android.cursor.item

Ÿ 如果返回数据是多条数据:vnd.android.cursor.dir

public class PersonProvider extends android.content.ContentProvider

{

private

static final int PERSON = 0;

private

static final int PERSON_ID = 1;

private

UriMatcher matcher;

private

DBOpenHelper helper;

@Override

public

boolean onCreate() {

matcher = new UriMatcher(UriMatcher.NO_MATCH);

matcher.addURI("com.demo.sqlite.provider", "person", PERSON); //

添加一个可以匹配的Uri

matcher.addURI("com.demo.sqlite.provider", "person/#",

PERSON_ID);

helper = new DBOpenHelper(getContext());

return true;

}

@Override

public

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

String[] selectionArgs, String sortOrder) {

switch (matcher.match(uri)) { // 对Uri进行匹配

case PERSON_ID:

String idSelection = "id = " +

ContentUris.parseId(uri); // Converts the last path segment to a

long.

// 注意此处字符串拼装

selection = selection == null ? idSelection : idSelection + " AND "

+ selection;

case PERSON:

SQLiteDatabase db = helper.getReadableDatabase();

return db.query("person", projection, selection, selectionArgs,

null, null, sortOrder);

default:

throw new IllegalArgumentException("No Match Uri " + uri);

}

}

@Override

public Uri

insert(Uri uri, ContentValues values) {

switch (matcher.match(uri)) {

case PERSON:

SQLiteDatabase db = helper.getWritableDatabase();

long id = db.insert("person", null,

values); // 使用 db.insert() 方法插入数据,返回 id

// 而 db.exceSQL(sql)方式插入数据,返回 void

//

return Uri.parse("content://com.demo.sqlite.provider/person/" +

id); // 与下句效果相同

return ContentUris.withAppendedId(uri,

id); // Appends the given ID to the end of the path.

default:

throw new IllegalArgumentException("No Match Uri " + uri);

}

}

@Override

public int

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

switch (matcher.match(uri)) {

case PERSON_ID:

long id = ContentUris.parseId(uri);

selection = selection == null ? "id = " + id : "id = " +id + " AND

" +selection;

case PERSON:

SQLiteDatabase db = helper.getWritableDatabase();

// return : The number of rows affected

return db.delete("person", selection, selectionArgs);

default:

throw new IllegalArgumentException("No Match Uri " + uri);

}

}

@Override

public int

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

selectionArgs) {

switch (matcher.match(uri)) {

case PERSON_ID:

long id = ContentUris.parseId(uri);

selection = selection == null ? "id = " + id : "id = " + id + " AND

" + selection;

case PERSON:

SQLiteDatabase db = helper.getWritableDatabase();

// @return the number of rows affected

return db.update("person", values, selection, selectionArgs);

default:

throw new IllegalArgumentException("No Match Uri " + uri);

}

}

@Override

public

String getType(Uri uri) {

switch (matcher.match(uri)) {

case PERSON_ID:

return "vnd.android.cursor.item/person";

case PERSON:

return "vnd.android.cursor.dir/person";

default:

throw new IllegalArgumentException("No Match Uri " + uri);

}

}

1.5. 访问内容提供者

Ÿ 通过Context获得ContentResolver对象

Ÿ 调用ContentResolver对象的方法即可访问内容提供者

private

static final String TAG = "ProviderTest";

// 查询 id

= 36

public void

testQuery1() {

// 通过 ContentResolver 调用 ContentProvider 提供的方法

ContentResolver resolver = getContext().getContentResolver();

Uri uri =

Uri.parse("content://com.demo.sqlite.provider/person");

Cursor c = resolver.query(uri, new String[] { "id", "name",

"balance" }, "id = ?", new String[] { "36" }, null);

if (c.moveToNext()) {

Person person = new Person(c.getInt(0), c.getString(1),

c.getInt(2));

Logger.i(TAG, person.toString());

}

}

// 查询所有

person

public void

testQuery2() {

// 通过 ContentResolver 调用 ContentProvider 提供的方法

ContentResolver resolver = getContext().getContentResolver();

Uri uri =

Uri.parse("content://com.demo.sqlite.provider/person");

Cursor c = resolver.query(uri, null, null, null, null);

while (c.moveToNext()) {

Person person = new Person(c.getInt(0), c.getString(1),

c.getInt(2));

Logger.i(TAG, person.toString());

}

}

// 通过附带

id 查询 person

public void

testQuery3() {

// 通过 ContentResolver 调用 ContentProvider 提供的方法

ContentResolver resolver = getContext().getContentResolver();

// Uri

Uri uri =

Uri.parse("content://com.demo.sqlite.provider/person/55");

Cursor c = resolver.query(uri, null, "name = ?", new String[] {

"Ashia_54" }, null);

while (c.moveToNext()) {

Person person = new Person(c.getInt(0), c.getString(1),

c.getInt(2));

Logger.i(TAG, person.toString());

}

}

public

void testInsert() {

ContentResolver resolver = getContext().getContentResolver();

Uri uri =

Uri.parse("content://com.demo.sqlite.provider/person");

ContentValues values = new ContentValues();

Person person = new Person("another Person uri insert",

7000);

values.put("name", person.getName());

values.put("balance", person.getBalance());

Uri reUri = resolver.insert(uri, values);

Cursor c = resolver.query(reUri, null, null, null, null);

if (c.moveToNext()) {

Person rePerson = new Person(c.getInt(0), c.getString(1),

c.getInt(2));

Logger.i(TAG, rePerson.toString());

}

}

public void

testDelete() {

// ContentResolver :This class provides applications access to the

content model.

ContentResolver resolver =

getContext().getContentResolver(); Uri url =

Uri.parse("content://com.demo.sqlite.provider/person/121");

// 忘记加 = ?, 异常如下

// android.database.sqlite.SQLiteException: bind or column index

out of range

long id = resolver.delete(url, "name = ?", new String[]

{"zhangsan"});

Logger.i(TAG, id + "");

id = resolver.delete(url, null, null);

Logger.i(TAG, id + "");

}

public void

testDeleteAll() {

ContentResolver resolver = getContext().getContentResolver();

Uri url =

Uri.parse("content://com.demo.sqlite.provider/person");

int deleteNum = resolver.delete(url, null, null);

Logger.i(TAG, deleteNum + "");

}

public void

testUpdate() {

ContentResolver resolver = getContext().getContentResolver();

Uri uri =

Uri.parse("content://com.demo.sqlite.provider/person/122");



推荐阅读
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了如何在Mac上使用Pillow库加载不同于默认字体和大小的字体,并提供了一个简单的示例代码。通过该示例,读者可以了解如何在Python中使用Pillow库来写入不同字体的文本。同时,本文也解决了在Mac上使用Pillow库加载字体时可能遇到的问题。读者可以根据本文提供的示例代码,轻松实现在Mac上使用Pillow库加载不同字体的功能。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
author-avatar
Jason剑豪
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有