对数据库的操做,咱们常常避免不了进行事务处理,这样能够减小对数据库操做的次数,从而提升了读写数据库的效率。以前博主对ContentProvider基本使用和涉及的知识点有个大体的归纳,这里就不详叙了,今天主要说一下如何使用ContentProvider处理事务以及对数据库的表进行监控。 java
1、经过ContentProvider实现对数据库进行批处理 android
咱们知道通常对数据库操做有两种方式,一种使用封装好的ContentProvider给外部(其余进程或者对象)进行数据库操做,另一种直接经过SQLiteDatabase执行sql语句,达到对数据库增删改查效果。
sql
如在使用SQLiteDatabase进行数据库操做的时候 数据库
DatabaseHelper dbhelper = new DatabaseHelper(ctx); SQLiteDatabase db =dbhelper.getWritableDatabase(); StringBuffer sb = new StringBuffer(); sb.append("CREATE TABLE IF NOT EXISTS "); sb.append(DvbNetworkDatabase.TransportStreams.TABLE_NAME); sb.append(" ("); sb.append(TransportStreams._ID).append(" INTEGER PRIMARY KEY,"); sb.append(TransportStreams.FREQUENCY).append(" INT,"); sb.append(TransportStreams.DEVLIVERY_TYPE).append(" INT,"); sb.append(TransportStreams.TRANSPORT_STREAM_ID).append(" INT,"); sb.append(TransportStreams.MPEG_TRANSPORT_STREAM_ID).append(" INT,"); sb.append(TransportStreams.NETWORK_ID).append(" INT,"); sb.append(TransportStreams.ORIGINAL_NETWORK_ID).append(" INT,"); sb.append(TransportStreams.INFO_VERSION).append(" INT,"); sb.append(TransportStreams.TUNE_PARAM).append(" TEXT);"); createTSTableSql = sb.toString(); db.execSQL(createTSTableSql);
使用SQLiteDatabase实现事务批处理 app
SQLiteDatabase db =mOpenHelper.getWritableDatabase(); db.beginTransaction();//开始事务 //进行insertdelete update等数据库操做 db.setTransactionSuccessful();//设置事务标记为Successful db.endTransaction();//提交事务
在使用SQLiteDatabase对数据库操做,咱们通常都是在应用里面(同一个进程下)实现的,如今经过ContentProvider对外接口,咱们如何实现呢?咱们能够翻一下官网文档或者查看一下源码发现有一个applyBatch的方法,Override this to handle requests to perform a batch of operations(重写此处理请求执行批量操做) ide
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws OperationApplicationException { SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); db.beginTransaction();// 开始事务 try { ContentProviderResult[] results = super.applyBatch(operations); db.setTransactionSuccessful();// 设置事务标记为successful return results; } finally { db.endTransaction();// 结束事务 Uri uri = null; for (ContentProviderOperation opt : operations) { if (opt.getUri().equals(uri)) { continue; } uri = opt.getUri(); getContext().getContentResolver().notifyChange(opt.getUri(), null); Log.i(TAG, "notifychange endTransaction..uri:" + opt.getUri()); } } }
当咱们经过ContentProvider执行批处理时以下方法 post
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); //删除操做 String[] args = new String[] { String.valueOf(GROUP_ID), String.valueOf(USER_ID) }; ops.add(ContentProviderOperation.newDelete(uri).withSelection(DEL_SELECTTION, args) .build()); //增长操做 value为ContentValue ops.add(ContentProviderOperation.newInsert(uri).withValues(value).build()); //修改操做 ……newUpdate……
2、经过ContentObserver实现对数据库表进行监控 ui
一般咱们对某一个数据进行监控,都会去建立一个线程达到对数据监控的效果,这样作对cpu占用率和内存开销是很大的,在对数据库表进行监控,android提供了一套完善的机制,使用ContentProvider。
ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引发的数据库的变化,继而作一些相应的处理,它相似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为,表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,固然这是与它所监听的Uri MIME Type有关的。
经过ContentObserver对数据库表/行进行监控,咱们须要实现下面三个步骤:
this
一、建立咱们特定的ContentObserver派生类,必须重载onChange()方法去处理回调后的功能实现
二、利用context.getContentResolover()得到ContentResolove对象,接着调用registerContentObserver()方法去注册内容观察者,为指定的Uri注册一个ContentObserver派生类实例,当给定的Uri发生改变时,回调该实例对象去处理。
三、因为ContentObserver的生命周期不一样步于Activity和Service等,所以,在不须要时,须要手动的调用unregisterContentObserver ()去取消注册。 spa
public ContentObserver setChannelObserver(){ channelObserver = new ContentObserver(channelHandler) { public void onChange(boolean selfChange) { Log.i("3--3", "--------------go in Observe channelObserver"); postLoadChannels(); }; }; return channelObserver; } …… context.getContentResolver().registerContentObserver(channelsUri, false, setChannelObserver()); ……