在Android世界里,ContentProvider将数据存储抽象成了类似SQL的形式,通过insert, delete, update, query等接口实现对数据的增删改查。通过ContentProvider,其所在应用程序和其他应用程序都可以通过URI访问数据源中的内容。被ContentProvider封装的数据源理论上可以是任何东西,但最常见的仍然是数据库。
构建一个ContentProvider最基本的流程如下:
一、元数据
包括整个数据源的元数据和各数据表格的元数据。对于整个数据源,需要提供的元数据包括其URI的authority部分、数据库名、数据表名、版本等等。对于数据表,应实现BaseColumn接口(以便获得如_id在内的默认列名),并在其中存放表名、MIME Type、URI等。
二、数据库访问类
这个类应该继承自SQLiteOpenHelper,一般作为ContentProvider具体类的内部类,并且ContentProvider需要持有它的引用。需要实现三个函数。
  1. 构造函数:至少要向父类型的构造函数传递数据库名、版本和Context等内容。
  2. onCreate:传入参数是一个SQLiteDatabase实例,可再次执行SQL语句创建数据表。(SQLiteDatabase.execSQL)
  3. onUpgrade:当版本升级的时候,参数包括数据库的实例、旧版本和新版本,通过增加列等手段来更新数据库的结构。最简单粗暴的方式,就是把已有内容删除,调用onCreate重新建立。
三、ContentProvider的实现类
这个类应该继承自ContentProvider。在其中需要实现如下内容:
  1. 列映射:将数据库中的列做一层抽象,保存在静态的Map<String, String>中。
  2. URI匹配:创建一静态UriMatcher对象,将合法的URI存入。它仍是类似字典的结构,将URI关联到一个整型常量,以供别处使用。
  3. onCreate:在ContentProvider首次被访问是调用。可选择在此创建SQLiteOpenHelper类的实例,但是官方文档中提倡将创建数据库的内容延后操作。
  4. getType:从URI得MIME type的方法。【*】
  5. query: 【**】根据不同的URI,尝使用SQLiteQueryBuilder类辅助查询。(新建对象后,调用SQLiteQueryBuilder.setTables, ~.setProjectionMap, ~.appendWhere等等)。而后从SQLiteOpenHelper字段中获取可读数据库对象,用qb.query方法执行查询。查询的结果通过Cursor对象返回。
  6. insert: 除了URI之外,还需要检查输入的ContentValues对象(键值对)是否完整。而后获取可写的数据库对象,调用其insert方法。如果插入成功,将返回新插入内容的URI,此时应调用getContext().getContentResolver().notifyChange()来通知数据源的观察者。
  7. delete, update: 类似insert,重点在于要根据不同类型的URI采取不同的策略进行删改。此外,这两个方法会返回受到影响的数据记录的数量。
四、在AndroidManifest.xml中声明
在provider标签中,必须要有
            android:authorities="ContentProvider对应的URI的authority段"
            android:name="ContentProvider的类型名"
五、使用ContentProvider
我的理解是,ContentProvider像一个提供数据的服务器。在Activity中,如果想使用某个ContentProvider,应通过URI、以ContentResolver作为客户端进行访问。为防止ANR的出现,应该使用异步方式访问数据源,如继承AsyncQueryHandler类型。对于查询操作的结果,可以通过ListView、CursorAdatper等之类型的配合来呈现给UI。
注释:
【*】其最常见的用途并非直接在ContentProvider中使用,而是在隐式启动Activity的时候。有时声明Activity时在AndroidManifest.xml文件中指定<data android:mimeType="someType">标签。这种情况下,尝试启动Activity时传入的Intent对象的data字段一 般是一个URI,系统就可以通过getType()方法找到对应的MIME Type来匹配相应的Activity。
【**】增、改、查诸方法,均需要解析给定的URI,用前面已经设置好的UriMatcher来判定URI对象的种类。

ContentProvider初阶Cookbook的更多相关文章

  1. Nodejs初阶之express

    PS: 2014/09/24 更新<Express 4.X 启航指南>,欢迎阅读和评论:)   老规矩,开头部分都是些自娱自乐的随想,想到哪写到哪... 到今天俺已经在俺厂工作俩年零几天了 ...

  2. R语言实战(一)介绍、数据集与图形初阶

    本文对应<R语言实战>前3章,因为里面大部分内容已经比较熟悉,所以在这里只是起一个索引的作用. 第1章       R语言介绍 获取帮助函数 help(), ? 查看函数帮助 exampl ...

  3. 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】

    平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是 ...

  4. 重温ASP.NET WebAPI(一)初阶

    重温ASP.NET WebAPI(一)初阶   前言 本文为个人对WebApi的回顾无参考价值.主要简单介绍WEB api和webapi项目的基本结构,并创建简单地webaapi项目实现CRUD操作. ...

  5. 《R语言实战》读书笔记--第三章 图形初阶(一)

    3.1使用图形 可以使用pdf等函数将图形直接保存在文件中.在运用attach和detach函数的使用中经常出现错误,比如命名重复的问题,所以,应该尽量避免使用这两个函数. plot是一般的画图函数, ...

  6. UE4开发神秘海域类游戏原型 初阶(二):动画资源的整合

    前一篇已经确定神海类游戏原型的目标,首先要做的就是3C's(Character, Controls, Camera)的开发.   UE4的3C's的程序部分开发主要也就是基于他的GamePlay Fr ...

  7. R语言—图像初阶

    dev.new() 创建一个新图像之前打开一个新的窗口 win.graph() 同上 pch() 指定绘制点时使用的符号 cex() 指定符号的大小,是一个数值,表示绘图符号相当于默认大小的缩放倍数 ...

  8. QT 初阶 第二章 创建对话框(查找对话框实例)

    最终效果图: 该对话框由三个文件组成:finddialog.h .finddialog.cpp. main.cpp 代码+注释 /*--finddialog.h--*/ #ifndef FINDDIA ...

  9. QT 初阶 1.3 节 控件的几何排列

    #include "mainwindow.h" #include <QApplication> #include <QHBoxLayout> #includ ...

随机推荐

  1. ORACLE里的自增字段设置

    大家都知道吧,这很坑,尤其是用惯了mysql里的自增字段设置,结果oracle里面没有的.oh,no 我用的是12c版本的,它有一个新特性,可以这样设置自增序列,在创建表是,把id设置为自增序列 cr ...

  2. linux系统 web在线日志分析

    线上环境出现问题时,不能像本地环境一样,断点查找问题,只有根据日志分析来定位问题,当然有资深的经验也是可以的,哈哈. 最基本的就是cat命令,可以通过cat filename,来查看文件全部内容, & ...

  3. SGU 296.Sasha vs. Kate(贪心)

    题意: 给出长度为n(<=1000)的一个数.输出删掉k个数字后的最大值. Solution: 简单贪心. s[i]代表数字s的第i位. 从前往后第一个满足s[i]>s[i-1]的位置,最 ...

  4. Windows phone 之Image控件

    wp目前支持的图片格式为png和jpeg ,我们可以通过设置Source属性设置图片源. 还有两个属性是:Stretch,Opacity Stretch属性 image的拉伸行为有此属性决定,此属性是 ...

  5. 不同的路径 II

    class Solution { public: /** * @param obstacleGrid: A list of lists of integers * @return: An intege ...

  6. HttpWebRequest 写入报错

    HttpWebRequest以UTF-8编码写入内容时发生“Bytes to be written to the stream exceed the Content-Length bytes size ...

  7. InstallShield:自己备份

    LIST listData;//声明listData listData = ListCreate(STRINGLIST);//创建一个空的实际字符串或数字列表. //参数都是在上个界面中赋值,然后在下 ...

  8. C# Winform开发框架模块图(平台核心模块+示例模块)

    企业版V4.0 - 模块图   企业版V4.0 - 项目解决方案   Client/Server构架,有两个解决方案:     客户端解决方案说明:     服务端解决方案说明: C/S系统开发框架- ...

  9. 那些年被我坑过的Python——邂逅与初识(第一章)

    第一问:为什么学习Python? 虚妖说:为了还债,还技术债,很早接触编程,却一直徘徊,也码了很多代码,却从未真真学会编程! 第二问:什么是Python 是一种以简洁.优雅著称的解释型.动态.强类型的 ...

  10. mssql 获取表结构信息

    SELECT (case when a.colorder=1 then d.name else null end) 表名, a.colorder 字段序号,a.name 字段名, (case when ...