zoukankan      html  css  js  c++  java
  • ContentProvider学习小结

    ContentProvider学习小结

    对于Android的一个应用程序,数据存储操作是必不可少的。因此,Android系统提供了五种数据存储方式,分别是:SharedPreferences、SQLite、Content Provider、File和网络存储。由于Android系统中,数据基本都是私有的,一般存放在属于自己的“data/data/程序包名”目录下,要在不同的应用之间实现数据共享,常用的方式是使用Content Provider。

          SQLite SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据存储方式。Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。

    SharedPreferences 一种常用的数据存储方式,常用于存储比较简单的数据配置参数,其本质就是一个存储key-value键值对数据的xml文件,其存储位置在/data/data/<包名>/shared_prefs目录下。 SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。

        File 即常说的文件(I/O)存储方法,常用于存储大量的数据,但缺点是更新数据困难。在Android中通常使用File存储方式是用Context.openFileOutput(String fileName, int mode)和Context.openFileInput(String fileName),通过数据流进行操作。

        网络存储:通过Android的网络数据包保存数据在网络上,需要网络的支持。

    以上四种存储操作一般针对的是应用本身的数据,如果要对其它应用的数据进行操作,那么ContentProvider将是很好的选择。ContentProvider为存储和读取数据提供了统一的接口,使应用程序可以实现数据共享,Android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)。使用ContentProvider的好处是开发人员不需要考虑数据内部是怎么存储的,比如说如果我们想利用ContenProvider来存数据,只需告诉insert函数该ContentProvider的uri和想存入的数据(包括列名和数值),查询时也是一样,只需输入Uri和查询的表,列名和查询条件,至于ContentProvider里面是怎么进行这些操作的我们不需要知道。

    ContentProvider通过Uri类进行匹配关联,例如:Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")。在ContentProvider中使用的查询字符串有别于标准的SQL查询。很多诸如select, add, delete, modify等操作我们都使用一种特殊的URI来进行,URI为通用资源标识符,它代表的是要操作的数据,Android中的每一种资源(比如文本,图像,视频等)都可以用Uri来表示。Android中的Uri由以下三部分组成:”content://”(即authory) ,数据的路径,资源标识ID(可选)。其中如果存在ID,则表示某一个具体的资源,如果不存在ID,则表示路径下的整体。以下是一些示例Uri:

         content://media/internal/images  这个URI将返回设备上存储的所有图片
         content://contacts/people/  
    这个URI将返回设备上的所有联系人信息
         content://contacts/people/45 
    这个URI返回单个结果(联系人信息中ID45的联系人记录)

    当使用ContentProvider在不同的应用程序中共享数据时,其数据的暴露方式是采取类似数据库中表的方法。而ContentResolver 恰好是采用类似数据库的方法来从ContentProvider中存取数据的,它是通过Uri来查询ContentProvider中提供的数据,查询时,还需知道目的数据库的名称,数据段的数据类型,或者说资源的ID。

    下面是新建ContentProvider的完整流程:

    1. 创建一个继承了ContentProvider父类的类,实现基本的query(),insert(),update(),delete()等方法,这些方法也是暴漏给其它应用调用的数据操作方法。
    2. 在自己应用的AndroidManifest.xml中使用<provider>标签来设置定义我们实现的ContentProvider。
    3. 定义一个名为CONTENT_URI,类型为public static final的Uri类型的类变量,你必须为其指定一个唯一的字符串值,最好的方案是以类的全名称,这也是你查找ContentProvider的唯一标示,此定义与你在上面AndroidManifest.xml中的<provider>标签中的android:authorities="downloads"是一致的。
    4. 定义你要返回给客户端的数据列名,此变量就是外部应用对你的数据进行操作的具体字段,一般与你在本地存储数据的变量名尽量保持一致,这样也便于理解调用。如果你正在使用Android数据库,必须为其定义一个叫_id的列,它用来表示每条记录的唯一性。
    5. 创建你的数据存储系统。大多数ContentProvider使用Android文件系统或SQLite数据库来保持数据,但是你也可以以任何你想要的方式来存储。数据的实际存储位置就在于此,ContentProvider只是对它进行了一次封装,并且在实现ContentProvider的接口方法时,会写明具体操作本地存储数据的步骤。              。
    6. 如果你要存储字节型数据,比如位图文件等,数据列其实是一个表示实际保存文件的URI字符串,通过它来读取对应的文件数据。处理这种数据类型的Content Provider需要实现一个名为_data的字段,_data字段列出了该文件在Android文件系统上的精确路径。这个字段不仅是供客户端使用,而且也可以供ContentResolver使用。客户端可以调用ContentResolver.openOutputStream()方法来处理该URI指向的文件资源;如果是ContentResolver本身的话,由于其持有的权限比客户端要高,所以它能直接访问该数据文件。
    7. 查询返回一个Cursor类型的对象。所有执行写操作的方法如insert(), update() 以及delete()都将被监听。我们可以通过使用ContentResover().notifyChange()方法来通知监听器关于数据更新的信息。

    下面是关于DownloadProvider的简单介绍:

    1. DownloadManager是系统对DownloadProvider的操作管理类,该类中定义了相关的下载操作,对外进一步封装数据操作已供外部调用。路径如下:

    frameworksasecorejavaandroidappDownloadManager.java

    浏览器下载文件先调用DownloadManager的enqueue函数进行下载,enqueue函数主要是将用户发送的Request实例分解组成一个ContentValues实例,接着它会执行ContentResolver.insert(Downloads.Impl. ALL_DOWNLOADS_CONTENT_URI, values),这个函数就是 DownloadProvider实现的insert函数,通过它把下载信息添加到数据库中,最后enqueue函数返回插入这条数据后返回的ID。

    1. Downloads类定义了外部操作DownloadProvider的相关字段。路径如下:

    frameworksasecorejavaandroidproviderDownloads.java

    在这个类中定义了DownloadProvider的相关字段变量,例如:Uri ALL_DOWNLOADS_CONTENT_URI =Uri.parse("content://downloads/all_downloads")就是定义了它的唯一地址,以便于外部应用直接通过ContentResolver调用此Uri查找DownloadProvider中的数据;String _DATA = "_data"定义了下载文件保存路径对应的列字段;COLUMN_MIME_TYPE = "mimetype"定义了下载文件的类型等

    3 .DownloadProvider位于packagesprovidersDownloadProvider路径下,继承重写ContentProvider的基本数据操作函数delete(),query(),insert(),update(),getType()等,外部应用通过ContentResolver就可以操作这些函数,方便不同应用之间数据共享操作。DatabaseHelper是继承SQLiteOpenHelper的内部类,在这里建立的数据库(DB_NAME = “downloads.db”)就是DownloadProvider保存数据的位置,而数据库中的表(DB_TABLE = “downloads”)就是所有下载文件的详细信息列表。

  • 相关阅读:
    再次或多次格式化导致namenode的ClusterID和datanode的ClusterID之间不一致的问题解决办法
    Linux安装aria2
    POJ 3335 Rotating Scoreboard 半平面交
    hdu 1540 Tunnel Warfare 线段树 区间合并
    hdu 3397 Sequence operation 线段树 区间更新 区间合并
    hud 3308 LCIS 线段树 区间合并
    POJ 3667 Hotel 线段树 区间合并
    POJ 2528 Mayor's posters 贴海报 线段树 区间更新
    POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
    POJ 3468 A Simple Problem with Integers 线段树成段更新
  • 原文地址:https://www.cnblogs.com/kevincode/p/4083409.html
Copyright © 2011-2022 走看看