Android四大组件——ContentProvider的增删改查和优化

ContentProvider的增删改查和优化


事先说明:

ContentProvider步骤:创数据库,写规则匹配,配置manifests,另一个应用使用

其实ContentProvider就是:在一个匹配器中写入自己写好的匹配规则,并对外提供写好的匹配规则供使用,剩下的就是增删改查的处理
细节处理:

在增删改查中的查询中,是没有cursor.getBoolean这个方法的,所以要对数据库中获取布尔值进行处理:

msg.setFlag(cursor.getInt(cursor.getColumnIndex("flag")) != 0);


ContentProvider的增删改查
步骤一:创建一个类继承SQLiteOpenHelper,并用SQL语句创建一个SQLite

        public class CommonOpenHelper extends SQLiteOpenHelper {
     
        private static CommonOpenHelper helper;
     
        public static CommonOpenHelper getInstance(Context context) {
            if (helper == null) {
                helper = new CommonOpenHelper(context, "common.db", null, 1);
            }
            return helper;
        }
     
        private CommonOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
            super(context, name, factory, version);
        }
     
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("create table message(" +
                    "id integer primary key autoincrement, " +
                    "content varchar, " +
                    "date varchar " +
                    ")");
        }
     
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
     
        }
    }


步骤二:创建一个类继承ContentProvider,提供增删改查的方法

        public class MyMessageProvider extends ContentProvider {
     
        //数据库名
        public final static String DB_MESSAGE = "message";
     
        //放置一个数据库
        CommonOpenHelper helper;
        SQLiteDatabase db;
     
        //空白匹配器
        UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
     
        //自身的匹配规则
        final static int CODE_MESSAGE_INSERT = 0;
        final static int CODE_MESSAGE_QUERY = 1;
        final static int CODE_MESSAGE_DELETE = 2;
        final static int CODE_MESSAGE_UPDATE = 3;
     
        //主机名
        final static String authority = "com.handsome.nfcc";
        final static Uri BASE_URI = Uri.parse("content://com.handsome.nfcc");
        
        //写入该主机名的匹配规则
        {
            matcher.addURI(authority, "message/insert", CODE_MESSAGE_INSERT);
            matcher.addURI(authority, "message/query", CODE_MESSAGE_QUERY);
            matcher.addURI(authority, "message/delete", CODE_MESSAGE_DELETE);
            matcher.addURI(authority, "message/update", CODE_MESSAGE_UPDATE);
        }
     
        //对外提供的URI
        public interface URI {
            Uri CODE_MESSAGE_INSERT = Uri.parse("content://" + authority + "/message/insert");
            Uri CODE_MESSAGE_QUERY = Uri.parse("content://" + authority + "/message/query");
            Uri CODE_MESSAGE_DELETE = Uri.parse("content://" + authority + "/message/delete");
            Uri CODE_MESSAGE_UPDATE = Uri.parse("content://" + authority + "/message/update");
        }
     
        @Override
        public boolean onCreate() {
            helper = CommonOpenHelper.getInstance(getContext());
            db = helper.getWritableDatabase();
            return false;
        }
     
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
            switch (matcher.match(uri)) {
                case CODE_MESSAGE_QUERY:
                    Cursor cursor = db.query(DB_MESSAGE, projection, selection, selectionArgs, null, null, sortOrder);
                    //注册内容观察者,观察数据变化
                    cursor.setNotificationUri(getContext().getContentResolver(), BASE_URI);
                    return cursor;
                default:
                    throw new IllegalArgumentException("未识别的uri" + uri);
            }
        }
     
        @Override
        public String getType(Uri uri) {
            return null;
        }
     
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            switch (matcher.match(uri)) {
                case CODE_MESSAGE_INSERT:
                    long rowId = db.insert(DB_MESSAGE, null, values);
                    if (rowId == -1) {
                        //添加失败
                        return null;
                    } else {
                        //发送内容广播
                        getContext().getContentResolver().notifyChange(BASE_URI, null);
                        //添加成功
                        return ContentUris.withAppendedId(uri, rowId);
                    }
                default:
                    throw new IllegalArgumentException("未识别的uri" + uri);
            }
        }
     
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            switch (matcher.match(uri)) {
                case CODE_MESSAGE_DELETE:
                    int number = db.delete(DB_MESSAGE, selection, selectionArgs);
                    //发送内容广播
                    getContext().getContentResolver().notifyChange(BASE_URI, null);
                    return number;
                default:
                    throw new IllegalArgumentException("未识别的uri" + uri);
            }
        }
     
        @Override
        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
            switch (matcher.match(uri)) {
                case CODE_MESSAGE_UPDATE:
                    int number = db.update(DB_MESSAGE, values, selection, selectionArgs);
                    //发送内容广播
                    getContext().getContentResolver().notifyChange(BASE_URI, null);
                    return number;
                default:
                    throw new IllegalArgumentException("未识别的uri" + uri);
            }
        }
    }


步骤三:在manifests文件中配置你所写的ContentProvider

        <provider
                android:name=".Provider.MyMessageProvider"
                android:authorities="com.handsome.nfcc" />


步骤四:在另一个应用中写一个数据库的增删改查类,使用该ContentProvider

        public class MessageDao {
     
        /**
         * 添加数据
         */
        public static boolean insert(ContentResolver resolver, Message msg) {
            ContentValues values = new ContentValues();
            values.put("content", msg.getContent());
            values.put("date", DateUtils.showDate());
            resolver.insert(MyMessageProvider.URI.CODE_MESSAGE_INSERT, values);
            return true;
        }
     
     
        /**
         * 删除数据
         */
        public static void delete(ContentResolver resolver, int id) {
            resolver.delete(MyMessageProvider.URI.CODE_MESSAGE_DELETE, "id = " + id, null);
        }
     
        /**
         * 删除全部数据
         */
        public static void deleteAll(ContentResolver resolver) {
            resolver.delete(MyMessageProvider.URI.CODE_MESSAGE_DELETE, null, null);
        }
     
        /**
         * 查询数据
         *
         * @param resolver
         * @return
         */
        public static List<Message> query(ContentResolver resolver) {
            List<Message> list = new ArrayList<>();
            Cursor cursor = resolver.query(MyMessageProvider.URI.CODE_MESSAGE_QUERY, null, null, null, null);
            while (cursor.moveToNext()) {
                Message msg = new Message();
                msg.setDate(cursor.getString(cursor.getColumnIndex("date")));
                msg.setContent(cursor.getString(cursor.getColumnIndex("content")));
                msg.setId(cursor.getInt(cursor.getColumnIndex("id")));
                list.add(0, msg);
            }
            return list;
        }
     
     
    }


ContentProvider的优化

往往在一个项目中有很多的数据库,这个时候并不是重复的写ContentProvider代码,而是将所有数据库中放在一个ContentProvider中,提供一个查询表名的方法,并对其相应的表进行操作


步骤一:ContentProvider的代码优化(一套代码适用多个数据库)

    public class MyDataProvider extends ContentProvider {
     
        //数据库名
        public final static String DB_DATA = "data";
        public final static String DB_FETCH = "fetch";
        public final static String DB_MESSAGE = "message";
     
        //放置一个数据库
        CommonOpenHelper helper;
        SQLiteDatabase db;
     
        UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
     
        //自身的匹配规则
        final static int CODE_DATA = 0;
        final static int CODE_FETCH = 1;
        final static int CODE_MESSAGE = 2;
     
        //主机名
        final static String authority = "com.handsome.nfc";
        final static Uri BASE_URI = Uri.parse("content://com.handsome.nfc");
     
     
        //写入该主机名的匹配规则
        {
            matcher.addURI(authority, "data", CODE_DATA);
            matcher.addURI(authority, "fetch", CODE_FETCH);
            matcher.addURI(authority, "message", CODE_MESSAGE);
        }
     
        //对外提供的URI
        public interface URI {
            Uri DATA_CONTENT_URI = Uri.parse(BASE_URI + "/data");
            Uri FETCH_CONTENT_URI = Uri.parse(BASE_URI + "/fetch");
            Uri MESSAGE_CONTENT_URI = Uri.parse(BASE_URI + "/message");
        }
     
        /**
         * 获取数据库表名
         *
         * @param uri
         * @return
         */
        private String getTableName(Uri uri) {
            String tableName = null;
            switch (matcher.match(uri)) {
                case CODE_DATA:
                    tableName = DB_DATA;
                    break;
                case CODE_FETCH:
                    tableName = DB_FETCH;
                    break;
                case CODE_MESSAGE:
                    tableName = DB_MESSAGE;
                    break;
                default:
                    break;
            }
            return tableName;
        }
     
        @Override
        public boolean onCreate() {
            helper = CommonOpenHelper.getInstance(getContext());
            db = helper.getWritableDatabase();
            return false;
        }
     
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
            String tableName = getTableName(uri);
            if (tableName == null) {
                throw new IllegalArgumentException("非法Uri:" + uri);
            }
            Cursor cursor = db.query(tableName, projection, selection, selectionArgs, null, null, sortOrder);
            //注册内容观察者,观察数据变化
            cursor.setNotificationUri(getContext().getContentResolver(), BASE_URI);
            return cursor;
        }
     
        @Override
        public String getType(Uri uri) {
            return null;
        }
     
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            String tableName = getTableName(uri);
            if (tableName == null) {
                throw new IllegalArgumentException("非法Uri:" + uri);
            }
            long rowId = db.insert(tableName, null, values);
            if (rowId == -1) {
                return null;
            } else {
                //发送内容广播
                getContext().getContentResolver().notifyChange(BASE_URI, null);
                return ContentUris.withAppendedId(uri, rowId);
            }
        }
     
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            String tableName = getTableName(uri);
            if (tableName == null) {
                throw new IllegalArgumentException("非法Uri:" + uri);
            }
            int number = db.delete(tableName, selection, selectionArgs);
            //发送内容广播
            getContext().getContentResolver().notifyChange(BASE_URI, null);
            return number;
        }
     
        @Override
        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
            String tableName = getTableName(uri);
            if (tableName == null) {
                throw new IllegalArgumentException("非法Uri:" + uri);
            }
            int number = db.update(tableName, values, selection, selectionArgs);
            //发送内容广播
            getContext().getContentResolver().notifyChange(BASE_URI, null);
            return number;
        }
    }

步骤二:在各个不同的数据库中的使用

Data数据库通过名字查询示例

    private static boolean queryDataByName(ContentResolver resolver, String tag_id) {
            Cursor cursor = resolver.query(MyDataProvider.URI.DATA_CONTENT_URI, null, "tag_id = '" + tag_id + "'", null, null);
            if (cursor.moveToFirst()) {
                return true;
            }
            return false;
        }

Fetch数据库插入示例

    public static boolean insert(ContentResolver resolver, Fetch fetch) {
            ContentValues values = new ContentValues();
            values.put("fetch_num", fetch.getFetch_num());
            values.put("username", fetch.getUsername());
            values.put("installationId", fetch.getInstallationId());
            values.put("created", fetch.getCreated());
            values.put("date", System.currentTimeMillis());
            resolver.insert(MyDataProvider.URI.FETCH_CONTENT_URI, values);
            return true;
        }

Message数据库查询示例

     public static List<Message> query(ContentResolver resolver) {
            List<Message> list = new ArrayList<>();
            Cursor cursor = resolver.query(MyDataProvider.URI.MESSAGE_CONTENT_URI, null, null, null, null);
            while (cursor.moveToNext()) {
                Message msg = new Message();
                msg.setDate(cursor.getString(cursor.getColumnIndex("date")));
                msg.setContent(cursor.getString(cursor.getColumnIndex("content")));
                msg.setId(cursor.getInt(cursor.getColumnIndex("id")));
                list.add(0, msg);
            }
            return list;
        }

 

 

转载于:https://my.oschina.net/u/920274/blog/3063068

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值