我是靠谱客的博主 懵懂皮皮虾,最近开发中收集的这篇文章主要介绍Android中的ContentProvider小结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ContentProvider作用

  • 为存储和获取数据提供了统一的接口

  • 实现了不用应用间的数据共享

  • Android为常用数据(如声音、图片、视频和通讯录等)提供的默认的ContentProvider支持

相关概念介绍

ContentProvider简介

为了实现向其他应用共享数据,需要继承一个抽象类ContentProvider,并实现如下几个抽象方法。

public class MyProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
}

看到这些抽象方法的参数是不是和数据库的相关操作很像。因此一般情况下,我们都是用数据库来存储数据

Uri简介

  1. 概念:通用资源标示符(Uniform Resource Identifier)

  2. 组成部分:

    • scheme 访问资源的命名机制

    • authority 存放资源的主机名

    • path 资源自身的名称

  3. 格式:scheme://authority/path,其中authority还包括host的port。例如:

    content://com.cydia.test:200/login/username

    • content为scheme
    • com.cydia.test:200为authority(com.cydia.test为host,200为port)
    • login/username为path。

Sqlite简介

参考文章《Android中的数据库应用小结》

本应用内的provider构建

众所周知,ContentProvider是用来向其他应用共享本应用内的数据,因此,我们首先需要确定数据在本应用内的存储方式。而考虑到继承ContentProvider需要实现的抽象方法(与sqlite的操作方法太相似),我们使用sqlite来存储数据。

创建数据库: MySqliteHelper

public class MySqliteHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "cydia.db";
public static final int DB_VERSION = 3;
public static final String TABLE_NAME = "bookstore";
public static final String COLUMN_ID = "id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_AUTHOR = "author";
public static final String COLUMN_PRICE = "price";
public static final String COLUMN_PAGES = "pages";
public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
COLUMN_ID + " integer primary key autoincrement," +
COLUMN_NAME + " text NOT NULL," +
COLUMN_AUTHOR + " text," +
COLUMN_PRICE + " real," +
COLUMN_PAGES + " integer)";
public MySqliteHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}

创建数据管理类: DBManager

public class DBManager {
private volatile static DBManager sInstance;
private SQLiteDatabase db;
private DBManager(Context context) {
MySqliteHelper helper = new MySqliteHelper(context);
db = helper.getWritableDatabase();
}
public static DBManager getInstance(Context context) {
if (sInstance == null) {
synchronized (DBManager.class) {
if (sInstance == null) {
sInstance = new DBManager(context);
}
}
}
return sInstance;
}
public long add(ContentValues contentValues) {
return db.insert(MySqliteHelper.TABLE_NAME, null, contentValues);
}
public int delete(String whereClause, String[] whereArgs) {
return db.delete(MySqliteHelper.TABLE_NAME, whereClause, whereArgs);
}
public int update(ContentValues contentValues, String whereClause, String[] whereArgs) {
return db.update(MySqliteHelper.TABLE_NAME, contentValues, whereClause, whereArgs);
}
public Cursor query(String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy) {
return db.query(MySqliteHelper.TABLE_NAME, columns, selection,
selectionArgs, groupBy, having,
orderBy);
}
public void closeDB() {
db.close();
}
}

继承ContentProvider类

public class MyProvider extends ContentProvider {
private Context context;
private ContentResolver contentResolver;
private static final String AUTHORITY = "com.pptv.test";
private static final int ALL_BOOKS = 1;
private static final int SINGLE_BOOK = 1;
//匹配Uri
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
//匹配Uri为content://com.pptv.test/bookstore 返回整数1
uriMatcher.addURI(AUTHORITY, MySqliteHelper.TABLE_NAME, ALL_BOOKS);
//匹配Uri为content://com.pptv.test/bookstore/# 返回整数2,注#为通配符
//如content://com.pptv.test/bookstore/1 就返回2
uriMatcher.addURI(AUTHORITY, MySqliteHelper.TABLE_NAME + "/#", SINGLE_BOOK);
}
@Override
public boolean onCreate() {
context = getContext();
contentResolver = context.getContentResolver();
return true;
}
@Nullable
@Override
public String getType(Uri uri) {
if (uriMatcher.match(uri) == ALL_BOOKS) {
return "vnd.android.cursor.dir/" + MySqliteHelper.TABLE_NAME;
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
return "vnd.android.cursor.item/" + MySqliteHelper.TABLE_NAME;
}
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
Uri ret = null;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//uri为 content://com.pptv.test/bookstore 可以执行插入操作
long id = DBManager.getInstance(context).add(values);
ret = ContentUris.withAppendedId(uri, id);
contentResolver.notifyChange(ret, null);
}
//content://com.pptv.test/bookstore/4 没有插入权限
return ret;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int id = 0;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//content://com.pptv.test/bookstore 删除满足条件的所有记录
id = DBManager.getInstance(context).delete(selection, selectionArgs);
contentResolver.notifyChange(uri, null);
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
//content://com.pptv.test/bookstore/4 删除id=4的记录
long deleted_id = ContentUris.parseId(uri);
id = DBManager.getInstance(context).delete(MySqliteHelper.COLUMN_ID + "=?",
new String[]{deleted_id +""});
contentResolver.notifyChange(uri, null);
}
return id;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int id = 0;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//content://com.pptv.test/bookstore 更新满足条件的所有记录
id = DBManager.getInstance(context).update(values, selection, selectionArgs);
contentResolver.notifyChange(uri, null);
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
//content://com.pptv.test/bookstore/4 更新id=4的记录
long update_id = ContentUris.parseId(uri);
id = DBManager.getInstance(context).update(values, MySqliteHelper.COLUMN_ID + "=?",
new String[]{update_id +""});
contentResolver.notifyChange(uri, null);
}
return id;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor cursor = null;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//content://com.pptv.test/bookstore 查找满足条件的所有记录
cursor = DBManager.getInstance(context).query(projection, selection, selectionArgs,
null, null, sortOrder);
cursor.setNotificationUri(contentResolver, uri);
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
//content://com.pptv.test/bookstore/4 查找id=4的记录
long select_id = ContentUris.parseId(uri);
cursor = DBManager.getInstance(context).query(projection, MySqliteHelper.COLUMN_ID + "=?",
new String[]{select_id +""},
null, null, sortOrder);
cursor.setNotificationUri(contentResolver, uri);
}
return cursor;
}
}

UriMatcher的作用在于,控制不同Uri的操作权限以及操作内容
比如上述code所示:content://com.pptv.test/bookstore 执行查找其返回所有符合条件的记录,而content://com.pptv.test/bookstore/4 执行查找方法,其仅仅返回id为4的记录

在AndroidManifest中注册provider


<provider
android:name=".provider.MyProvider"
android:authorities="com.pptv.test"
android:enabled="true"
android:exported="true" />
  • android:authorities 访问这个provider的权限,需要和MyProvider中定义的AUTHORITY保持一致。
  • android:enabled 指定这个内容提供器是否能够被系统安装
  • android:exported 指定该内容提供器是否能够被其他的应用程序组件使用

其他应用使用Provider来访问数据

获取一个ContentResolver类

直接使用Content类的getContentResolver()方法就能获取到。

通过ContentResolver执行增删改查操作

ContentResolver的主要方法:

返回值函数声明
final Uriinsert(Uri url, ContentValues values)
final intdelete(Uri url, String where, String[] selectionArgs)
final intupdate(Uri uri, ContentValues values, String where, String[] selectionArgs)
final Cursorquery(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

例如:查询所有的数据


private String getData(){
StringBuilder sb =new StringBuilder();
ContentResolver cr = this.getContentResolver();
Uri uri = Uri.parse("content://com.pptv.test/bookstore");
Cursor cursor = cr.query(uri, null, null,null,null);
if(cursor != null){
Log.i(TAG, "cursor != null");
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
float price = cursor.getFloat(cursor.getColumnIndex("price"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
sb.append("name = " + name + ", ")
.append("author = " + author + ", ")
.append("price = " + price + " ,")
.append("pages = " + pages + "n");
}
cursor.close();
}
return sb.toString();
}

最后

以上就是懵懂皮皮虾为你收集整理的Android中的ContentProvider小结的全部内容,希望文章能够帮你解决Android中的ContentProvider小结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部