前言:

    总结这篇文章之前我们先来回顾一下Android Sqlite数据库,参考文章:http://www.cnblogs.com/whoislcj/p/5506294.html,Android程序内部数据存储如果使用Sqlite数据库,那么Android 如何实现程序间数据共享?Android 提供了一种机制可以实现程序间的数据共享,它就是Android 四大组件之一ContentProvider,Android为存储和获取数据提供统一的接口,用于实现程序间数据共享,不要将其理解为数据库。

     为什么说是熟悉又陌生呢?因为我们经常使用到,Android内置的许多数据都是采用ContentProvider,比如图片,视频,音频,手机联系人等,至于陌生那是因为我很少自己去实现一个ContentProvider,今天我们重点是来实现一个自定义ContentProvider。

ContentProvider类简介:

     1.) 我们一般要继承ContentProvider,那么要实现那些函数呢?
  • ContentProvider()   构造函数
  • onCreate()    创建数据时调用的回调函数
  • insert()      插入数据
  • delete()     删除数据
  • update()    更新数据
  • query()      查询数据
  • getType()  得到数据类型
   2.)URI简介:

     ContentProvider通过URI来访问数据执行增删改查的操作,一个完整的URI有 content://自定义ContentProvider/xxx数据库名称 

     我们先声明一个作用域:

    //访问URI作用域
    public static final String CONTENT_URI="com.whoislcj.testsqlite.personprovider";

    对应URI举例说明一下:

  • content://com.whoislcj.testsqlite.personprovider/person   返回person所以数据
  • content://com.whoislcj.testsqlite.personprovider/person/10 返回id为10的person数据
   3.)UriMatcher简介

       主要用于匹配Uri,为什么要匹配Uri呢?通过上面的Uri举例可以看出操作域不一样,对于执行一个delete、update、query来说我们要获取参数参数执行不能对应操作。

   使用:

  //定义一个UriMatcher类对象,用来匹配Uri的。
    private static final UriMatcher uriMatcher;
    //集合操作
    public static final int INCOMING_COLLECTION = 1;
    //单个ID操作
    public static final int INCOMING_SIGNAL = 2;
    static {
        //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        //如果match()方法匹配com.whoislcj.testsqlite.personprovider/person路径,返回匹配码为1
        uriMatcher.addURI(CONTENT_URI, "person", INCOMING_COLLECTION);//添加需要匹配uri,如果匹配就会返回匹配码
        //如果match()方法匹配content://com.ljq.provider.personprovider/person/230路径,返回匹配码为2
        uriMatcher.addURI(CONTENT_URI, "person/#", INCOMING_SIGNAL);//#号为通配符
    }
4.)ContentUris简介

      ContentUris是对URI的操作类,比如获取URI路径里的参数,或者给URI拼接一个参数

    举例说明:

  • long id = ContentUris.parseId(uri);//从uri中获取id
  • Uri rowUri = ContentUris.withAppendedId(uri, rowId);//uri追加id 生成该条数据完整的URI地址
  5.)ContentResolver简介   

       ContentResolver主要用于为外部程序提供增删改查的操作函数,也可以注册观察者来监听数据的变化。

 6.)自定义ContentProvider具体实现:
public class PersonProvider extends ContentProvider {
    // DatabaseHelper操作句柄
    private DBHelper dbHelper;
    //访问URI
    public static final String CONTENT_URI="com.whoislcj.testsqlite.personprovider";
    // 数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头
    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/person";
    // 单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头
    public static final String CONTENT_TYPE_ITME = "vnd.android.cursor.item/person";
    //定义一个UriMatcher类对象,用来匹配Uri的。
    private static final UriMatcher uriMatcher;
    //集合操作
    public static final int INCOMING_COLLECTION = 1;
    //单个ID操作
    public static final int INCOMING_SIGNAL = 2;
    static {
        //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        //如果match()方法匹配com.whoislcj.testsqlite.personprovider/person路径,返回匹配码为1
        uriMatcher.addURI(CONTENT_URI, "person", INCOMING_COLLECTION);//添加需要匹配uri,如果匹配就会返回匹配码
        //如果match()方法匹配content://com.ljq.provider.personprovider/person/230路径,返回匹配码为2
        uriMatcher.addURI(CONTENT_URI, "person/#", INCOMING_SIGNAL);//#号为通配符
    }

    public PersonProvider() {
    }

    /**
     * 回调函数,在ContentProvider创建的时候,就会运行
     * 作用获取操作用户的句柄
     */
    @Override
    public boolean onCreate() {
        //这里会调用 DBHelper的构造函数创建一个数据库;
        dbHelper = new DBHelper(getContext());
        return true;
    }

    /**
     * 执行插入数据函数
     *
     * @param uri
     * @param values
     * @return
     */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        //获取一个可写的数据库
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        //调用数据库的插入操作 也可以自己构造sql语句 执行  db.execSQL();相对比较麻烦
        long rowId = db.insert(DBHelper.TABLE_NAME, "", values);
        //判断是否插入成功
        if (rowId > 0) {
            Uri rowUri = ContentUris.withAppendedId(uri, rowId);//uri追加id 生成该条数据完整的URI地址
            getContext().getContentResolver().notifyChange(uri, null);
            return rowUri;
        }
        throw new SQLException("Failed to insert row" + uri);
    }

    /**
     * 删除数据操作
     *
     * @param uri
     * @param selection
     * @param selectionArgs
     * @return
     */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        //获取一个可写的数据库
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case INCOMING_COLLECTION:
                //执行删除操作
                count = db.delete(DBHelper.TABLE_NAME, selection, selectionArgs);
                getContext().getContentResolver().notifyChange(uri, null);
                break;
            case INCOMING_SIGNAL:
                long id = ContentUris.parseId(uri);//从uri中获取id
                String where = "> 删除指定id的记录
                where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : ""; // 把其它条件附加上
                count = db.delete(DBHelper.TABLE_NAME, where, selectionArgs);
                getContext().getContentResolver().notifyChange(uri, null);
                break;
            default:
                throw new SQLException("Failed to delete row " + uri);
        }
        //关闭数据库
        db.close();
        return count;
    }

    /**
     * 更新数据操作
     *
     * @param uri
     * @param values
     * @param selection
     * @param selectionArgs
     * @return
     */
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        //获取一个可写的数据库
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case INCOMING_COLLECTION:
                //执行更新数据
                count = db.update(DBHelper.TABLE_NAME, values, selection, selectionArgs);
                getContext().getContentResolver().notifyChange(uri, null);
                break;
            case INCOMING_SIGNAL:
                long id = ContentUris.parseId(uri);//从uri中获取id
                String where = "> 删除指定id的记录
                where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它条件附加上
                //执行更新数据
                count = db.update(DBHelper.TABLE_NAME, values, where, selectionArgs);
                getContext().getContentResolver().notifyChange(uri, null);
                break;
            default:
                throw new SQLException("Failed to update row " + uri);
        }
        //关闭数据库
        db.close();
        return count;
    }

    /**
     * 查询操作
     *
     * @param uri
     * @param projection
     * @param selection
     * @param selectionArgs
     * @param sortOrder
     * @return
     */
    @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 INCOMING_COLLECTION:
                //执行查询
                cursor = db.query(DBHelper.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case INCOMING_SIGNAL:
                long id = ContentUris.parseId(uri);//从uri中获取id
                String where = "> 删除指定id的记录
                where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它条件附加上
                cursor = db.query(DBHelper.TABLE_NAME, projection, where, selectionArgs, null, null, sortOrder);
                break;
            default:
                throw new SQLException("Failed to query " + uri);
        }
        return cursor;
    }

    /**
     * 该方法用于返回当前Url所代表数据的MIME类型。
     *
     * @param uri
     * @return
     */
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case INCOMING_COLLECTION:
                return CONTENT_TYPE;
            case INCOMING_SIGNAL:
                return CONTENT_TYPE_ITME;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }
}
View Code

相关文章:

  • 2021-11-27
  • 2021-04-26
  • 2021-09-22
  • 2021-09-10
  • 2021-10-15
  • 2021-09-17
  • 2021-10-26
猜你喜欢
  • 2021-05-23
  • 2021-07-19
  • 2021-05-28
  • 2023-02-17
  • 2021-10-30
  • 2021-06-20
  • 2021-10-29
相关资源
相似解决方案