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