android-数据持久化存储之Content Provider

1. Content Provider

SQLite保存了各个应用自己的数据库,各应用数据库之间无法访问,而Content Provider 则解决了这个问题,

它存储的数据可以被各个应用访问,可以在自己应用中创建Content Provider,也可以直接使用已存在的Content Provider。

2.ContentResolver

ContentResolver cr=Context.getContentResolver();//通过context获取该对象

在android中,应用无法直接访问Content Provider,必须通过ContentResolver 接口提供的方法访问它。

每个Content Provider类只有一个实例对象,它可以被多个应用中的ContentResolver 对象访问。

3.URI(Unified Resource Identifier,统一资源标识)

每个Content Provider存储的数据和SQLite一样,以表形式存储,但是除了表名,字段名。

Content Provider 要求每张表都有唯一的URI(如下DATA_URI),URI类似一个指示路径的

字符串。形式:<scheme>://<authority>/<path>?<query>。

对于Content Provider的数据表,<scheme>已经固定用“content”表示为Content Provider的数据表。

<authority>:为继承Content Provider具体类的类名。

<path>:为表名,如下面的AUTHOR_TABLE = "author";

操作修改生成新的URI的方式

Uri uri=Uri.parse("content://media/images/media");
    Uri uri1=ContentUris.withAppendedId(uri, 2);//常用于创建指向某个id记录的Uri
    Uri uri2=Uri.withAppendedPath(uri, "2");//常用于创建指向某张表的Uri

注意:方法里第一个参数后面没有”/”结尾。

public final class Publisher {

    private Publisher() {
    }
    public static final String AUTHOR_TABLE = "author";
    public static final String BOOK_TABLE = "book";
    public static final String BOOK_AUTHOR_TABLE = "book_author";
    public static final Uri CONTENT_URI = Uri.parse("content://"
            + PublisherProvider.PROVIDER_NAME);
    public static final Uri BOOK_AUTHOR_URI = Uri.withAppendedPath(CONTENT_URI,
            "book_authortable");

    public static class AUTHOR implements BaseColumns {
        public static final Uri DATA_URI = Uri.withAppendedPath(CONTENT_URI,
                "authortable");
        public static final String NAME = "author_name";
        public static final String ADDRESS = "address";
        public static final String PHONE = "phone";
        public static final String ORDER_BY = "author_name DESC";
    }

    public static class BOOK implements BaseColumns {
        public static final Uri DATA_URI = Uri.withAppendedPath(CONTENT_URI,
                "booktable");
        public static final String NAME = "book_name";
        public static final String AUTHOR_ID = "author_id";
        public static final String PUBLISH_YEAR = "public_year";
        public static final String ORDER_BY = "book_name DESC";
    }
}

4. Content Provider

android中自带的Content Provider都在”android.provider”包中,常用类如下:

Browser:读取或修改标签,浏览历史和网络搜素记录

CallLog:读取或修改通话记录

Contracts: 读取或修改联系人信息

MediaStore:提供对多媒体文件(音频,视频和图片)的读/写控制,并且可以全局访问

Settings:读取或修改设置信息。

5.声明Content Provider

在清单文件中声明:

<provider android:name=".PublisherProvider"
               android:multiprocess="false"
               android:authorities="PublisherProvider"
       />

authorities标签和name标签都是继承Content Provider具体类的类名。

5.1 Content Provider的加载机制

在android启动时,平台通过acquireProvider()方法来解析清单文件中Provider声明的

authority字段,并自动加载所有的相应Content Provider,而multiprocess属性值决定了

该Content Provider能否在多个应用进程中被创建。

multiprocess:false 是指其他应用要想使用该Content Provider,只能通过进程间通信(IPC)

方式调用该Content Provider对象。效果为同步操作该对象

multiprocess:true 是指其他应用可以在自己的应用进程中创建一个该Content Provider的实例
                                再去使用它,效果为不同步。

6.创建自定义的Content Provider

成员变量:打开数据库连接的OpenHelper,数据库对象db,URI匹配器,以及它的常量值,

如 int code, String type

SQLiteDatabase DB;
     PublisherDatabaseHelper mHelper

UriMatcher uriMatcher

需要覆盖的方法:

CRUD的方法其实是封装数据库对象db里的方法,只是需要URI匹配器解析Uri参数,存入db的方法里

public boolean onCreate()

public String getType(Uri uri)

public Cursor query(Uri uri, String[] projection,..)

public Uri insert(Uri uri, ContentValues values)

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

public int update(Uri uri, ContentValues values,..)

7.DAO接及实现

通过contentResolver对象里提供的方法操作自定义的Content Provider

public class ContentProviderDao implements PubliserDao {

    private static ContentProviderDao instance;
    private Context context;
    private ContentResolver contentResolver;

    private ContentProviderDao(Context ctx) {
        context = ctx;
        contentResolver = context.getContentResolver();
    }

    public static synchronized ContentProviderDao getInstance(Context ctx) {
        if (instance == null)
            instance = new ContentProviderDao(ctx);
        return instance;
    }

    public void deleteAuthor(long author_id) {
        contentResolver.delete(AUTHOR.DATA_URI, AUTHOR._ID + " = " + author_id,
                null);
    }

    public Cursor getAuthorById(long id) {
        return contentResolver.query(AUTHOR.DATA_URI, null, AUTHOR._ID + " = "
                + id, null, null);
    }

    public Cursor getAuthors() {
        return contentResolver.query(AUTHOR.DATA_URI, null, null, null,
                Publisher.AUTHOR.ORDER_BY);
    }

    public Cursor getBooksByAuthor(long author_id) {
        return contentResolver.query(Publisher.BOOK_AUTHOR_URI, null,
                BOOK.AUTHOR_ID + " = " + author_id, null, null);
    }

    public void insertAuthor(String name, String address, String phone) {
        ContentValues values = new ContentValues();
        values.put(Publisher.AUTHOR.NAME, name);
        values.put(Publisher.AUTHOR.ADDRESS, address);
        values.put(Publisher.AUTHOR.PHONE, phone);
        contentResolver.insert(AUTHOR.DATA_URI, values);
    }

    public void updateAuthor(long id, String name, String address, String phone) {
        Uri uri = ContentUris.withAppendedId(AUTHOR.DATA_URI, id);
        ContentValues values = new ContentValues();
        values.put(Publisher.AUTHOR.NAME, name);
        values.put(Publisher.AUTHOR.ADDRESS, address);
        values.put(Publisher.AUTHOR.PHONE, phone);
        contentResolver.update(uri, values, null, null);
    }

   public void deleteAuthors(String where) {
        contentResolver.delete(AUTHOR.DATA_URI, where, null);
    }

}
时间: 2024-12-16 20:00:53

android-数据持久化存储之Content Provider的相关文章

Android数据持久化存储

Android数据持久化存储共有四种方式,分别是文件存储.SharedPreferences.Sqlite数据库和ContentProvider.在本篇幅中只介绍前面三种存储方式,因为ContentProvider属于android四大组件之一,所以它的数据存储方式在介绍四大组件的时候说明. 1.文件存储 文件存储不对存储的内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中的,因而它比较适合用于存储一些简单的文本数据或二进制数据. 文件存储有两种方式,一是存储到手机内存中(memor

饿了么开源项目:便捷高效的Android数据持久化存储框架

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51436972 Android应用开发时经常要对许多数据进行持久化存储,便于以后访问. 对于int.double.boolean这些基本数据,可以使用SharedPreference.对于一些对象,往SharedPreference里存储的时候需要使用序列化技术.如果对象很大,或者碰到列表.数组等结构,就必须使用数据库.而使用数据库比较麻烦,成

iOS数据持久化存储

本文中的代码托管在github上:https://github.com/WindyShade/DataSaveMethods 相对复杂的App仅靠内存的数据肯定无法满足,数据写磁盘作持久化存储是几乎每个客户端软件都需要做的.简单如"是否第一次打开"的BOOL值,大到游戏的进度和状态等数据,都需要进行本地持久化存储.这些数据的存储本质上就是写磁盘存文件,原始一点可以用iOS本身支持有NSFileManager这样的API,或者干脆C语言fwrite/fread,Cocoa Touch本身

数据持久化存储

概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) preference(偏好设置) NSKeyedArchiver(归档) SQLite 3 CoreData 沙盒 在介绍各种存储方法之前,有必要说明以下沙盒机制.iOS程序默认情况下只能访问程序自己的目录,这个目录被称为“沙盒”. 1.结构 既然沙盒就是一个文件夹,那就看看里面有什么吧.沙盒的目

Swift - 使用Core Data进行数据持久化存储

一,Core Data介绍 1,Core Data是iOS5之后才出现的一个数据持久化存储框架,它提供了对象-关系映射(ORM)的功能,即能够将对象转化成数据,也能够将保存在数据库中的数据还原成对象. 2,虽然其底层也是由类似于SQL的技术来实现,但我们不需要编写任何SQL语句,有点像Java开发中的Hibernate持久化框架 3,Core Data数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型. 4,与SQLite区别:只能取出整个实体记录,然后分解,

iOS开发之数据持久化存储

概论 数据持久化存储:所谓持久化存储就是将数据保存到硬盘中,使得应用程序或者机器在重启后可以访问之前保存的数据. 常见方式: plist文件(属性列表) preference(偏好设置) NSKeyedArchiver(归档) SQLite3(数据库) CoreData(苹果基于数据库封装的持久化存储工具,这种方式效率不高,因为会帮我们动态生成很多重复的代码,我只有写XMPP的时候会用一下,因为XMPP里面的存储用的就是CoreData) 沙盒 说到持久化存储就不得不说一下苹果的沙盒机制,苹果的

redis的数据持久化存储

redis的数据持久化存储 Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化.Redis支持两种持久化方式: 一.snapshotting(快照)方式快照是默认的持久化方式.这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb.我们可以配置redis在n秒内如果超过若干个key被修改就自动做快照持久保存. 在约87行,有默认的快照策略(指定在多长时间内,有多少次更新操作,就将数据同步到数据快照文件,可以多个条件

[Xcode10 实际操作]七、文件与数据-(14)数据持久化存储框架CoreData的使用:删除CoreData中的数据

本文将演示如何删除数据持久化对象. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] 1 import UIKit 2 //引入数据持久化存储框架[CoreData] 3 import CoreData 4 5 class ViewController: UIViewController { 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 // Do any additional setup a

python 基础之数据持久化存储

###数据持久化存储 - 说明:持久化存储方案,普通文件.数据库.序列化 - 示例: ```python import pickle class Person: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return 'name:{} age:{}'.format(self.name, self.age) xiaoming = Person('xiaoming', 20) #