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);
    }

}

 

posted @ 2015-03-20 10:01  beyondbycyx  阅读(321)  评论(0编辑  收藏  举报