Content Provider
跨进程共享数据的标准方式
与SharedPreferences存储中的全局可读可写操作模式不同的是,Content Provider可选择只对某一部分数据进行共享,从而保证数据的安全性
ContentResolver
不同于SQLiteDatabase,ContentResolver中的增删改查方法均不接收表名参数,而是使用一个Uri的参数代替,这个参数被称作内容URI
内容URI:内容提供者中的数据的唯一标识符,由两部分组成:authority和path
authority:给不同应用程序做区分,为避免冲突,采用包名命名
path:给同一应用程序中不同表做区分,通常都会添加到authority后面
内容URI标准格式:content://包名/表名
只访问某表中指定id的数据:content://包名/表名/id
匹配任意表的内容:content://包名/*
匹配指定表的任意一行数据:content://包名/表名/#
*:表示匹配任意长度的任意字符
#:表示匹配任意长度的任意数字
获取Uri实例:Uri uri = new Uri.parse(内容URI); ****
//获取实例
ContentResolver resolver = Context.getContentResolver()
//增
Uri insert(Uri url, ContentValues values)
//删
int delete(Uri url, String where, String[] selectionArgs)
//改
int update(Uri uri, ContentValues values, String where, String[] selectionArgs)
//查
Cursor query(Uri uri, String[] projection, Bundle queryArgs,
CancellationSignal cancellationSignal)
基础使用
ContentProvider的创建
public class DatabaseProvider extends ContentProvider {
public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
public static final String authority = "com.example.provider";
private static UriMatcher uriMatcher;
private MyDatabaseHelper dbHelper; //内容提供器数据库支持
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(authority, "book", BOOK_DIR);
uriMatcher.addURI(authority, "book/#", BOOK_ITEM);
}
@Override
public boolean onCreate() {
//创建内容提供器要使用的数据库
dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
//必须返回true,否则内容提供器无法被使用
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
cursor = db.query("Book", projection, selection, selectionArgs,
null, null, sortOrder);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
cursor = db.query("Book", projection, "id = ?", new String[]
{ bookId }, null, null, sortOrder);
break;
}
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Uri uriReturn = null;
long newBookId = db.insert("Book", null, values);
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
uriReturn = Uri.parse("content://" + authority + "/book/" +
newBookId);
break;
case BOOK_ITEM:
uriReturn = Uri.parse("content://" + authority + "/book/" +
newBookId);
break;
}
return uriReturn;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int updatedRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
updatedRows = db.update("Book", values, selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
updatedRows = db.update("Book", values, "id = ?", new String[]
{ bookId });
break;
}
return updatedRows;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int deletedRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
deletedRows = db.delete("Book", selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
deletedRows = db.delete("Book", "id = ?", new String[] { bookId });
break;
}
return deletedRows;
}
@Override
//Uri对象所对应的MIME类型
//必须以vnd开头
//如内容URI以路径结尾,后接android.cursor.dir/;如以id结尾,后接android.cursor.item/
//最后接vnd.[authority].[path]
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd." + authority + ".book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd." + authority + ".book";
}
return null;
}
}
ContentProvider的访问
public void insert(View view) {
// 得到内容提供者的解析器
ContentResolver resolver = getContentResolver();
//获得内容提供者的uri,注意uri格式
Uri uri = Uri.parse("content://com.example.provider/book");
//创建ContentValues对象,目的是创建一个空的set集合,用于存储数据
ContentValues values = new ContentValues();
values.put("name", "zhangsan");
values.put("money", 10000);
// 通过内容解析器让内容提供者添加一条数据
resolver.insert(uri, values);
//注册内容观察者
resolver.registerContentObserver(uri, true, new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
}
});
}