文档章节

实现ContentProvider事务操作以及对数据库的监控

zhoulc
 zhoulc
发布于 2014/03/01 21:58
字数 1023
阅读 1527
收藏 2

    对数据库的操作,我们经常避免不了进行事务处理,这样可以减少对数据库操作的次数,从而提高了读写数据库的效率。之前博主对ContentProvider基本使用和涉及的知识点有个大致的概括,这里就不详叙了,今天主要说一下如何使用ContentProvider处理事务以及对数据库的表进行监控。

一、通过ContentProvider实现对数据库进行批处理

    我们知道一般对数据库操作有两种方式,一种使用封装好的ContentProvider给外部(其他进程或者对象)进行数据库操作,另外一种直接通过SQLiteDatabase执行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实现事务批处理

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(重写此处理请求执行批量操作)

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执行批处理时如下方法

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……


二、通过ContentObserver实现对数据库表进行监控

    通常我们对某一个数据进行监控,都会去创建一个线程达到对数据监控的效果,这样做对cpu占用率和内存开销是很大的,在对数据库表进行监控,android提供了一套完善的机制,使用ContentProvider。
    ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为,表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。
    通过ContentObserver对数据库表/行进行监控,我们需要实现下面三个步骤:

    1、创建我们特定的ContentObserver派生类,必须重载onChange()方法去处理回调后的功能实现
    2、利用context.getContentResolover()获得ContentResolove对象,接着调用registerContentObserver()方法去注册内容观察者,为指定的Uri注册一个ContentObserver派生类实例,当给定的Uri发生改变时,回调该实例对象去处理。
    3、由于ContentObserver的生命周期不同步于Activity和Service等,因此,在不需要时,需要手动的调用unregisterContentObserver ()去取消注册。

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());
……



    

 

© 著作权归作者所有

共有 人打赏支持
zhoulc
粉丝 49
博文 32
码字总数 47964
作品 0
深圳
程序员
私信 提问
Android四种数据存储方式

存储方式 Android提供以下四种存储方式: SharePreference SQLite File ContentProvider Android系统中数据基本都是私有的,一般存放在“data/data/程序包名”目录下。如果要实现数据共享,正...

我家的猫跳楼了
2015/09/09
35
0
android(4)事务处理,ContentProvider,ListView

一.SQLite数据库 1.事务 beginTransaction(); // 开始事务 setTransactionSuccessful(); // 设置成功点, 在事务结束时, 成功点之前的操作会被提交 endTransaction(); // 结束事务, 通常放在f...

会飞的蝌蚪
2014/03/31
0
0
Android通讯录数据库操作(转)

可以参考 这个博客http://www.uml.org.cn/mobiledev/201110121.asp 对contact2.db中的几个比较常用的表进行总结: 包括 contacts表,rawcontacts表,data表,phonelookup表 希望大家参照源代...

xiahuawuyu
2012/09/29
0
0
Android开发_Android数据的四种存储方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhangty0223/article/details/10701597 Android系统一共提供了四种数据存储方式。分别是:SharePreference、S...

张腾元_Ternence
2013/08/31
0
0
SharedPreferences多进程解决方案

由于进程间是不能内存共享的,每个进程操作的SharedPreferences都是一个单独的实例,这导致了多进程间通过SharedPreferences来共享数据是不安全的,这个问题只能通过多进程间其它的通信方式或...

cjh94520
2017/04/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

dockerfile 镜像构建(1)

通用dockerfile 利用已经编译好的.jar 来构建镜像。要构建的目录如下: [root@iZuf61quxhnlk9m2tkx16cZ demo_jar]# docker build -t demo:1 . 运行镜像: [root@iZuf61quxhnlk9m2tkx16cZ de...

Canaan_
今天
2
0
Redis radix tree源码解析

Redis实现了不定长压缩前缀的radix tree,用在集群模式下存储slot对应的的所有key信息。本文将详述在Redis中如何实现radix tree。 核心数据结构 raxNode是radix tree的核心数据结构,其结构体...

阿里云云栖社区
今天
13
0
vue import 传入变量

在做动态添加component的时候,传入变量就会报错,出现以下错误信息: vue-router.esm.js?fe87:1921 Error: Cannot find module '@/components/index'. at eval (eval at ./src/components ......

朝如青丝暮成雪
今天
3
0
Flutter开发 Dio拦截器实现token验证过期的功能

前言: 之前分享过在Android中使用Retrofit实现token失效刷新的处理方案,现在Flutter项目也有“token验证过期”的需求,所以接下来我简单总结一下在Flutter项目中如何实现自动刷新token并重...

EmilyWu
今天
9
0
final Map可以修改内容,final 常量不能修改

1.final Map 可以put元素,但是不可以重新赋值 如: final Map map = new HashMap(); map = new HashMap();//不可以 因为栈中变量map引用地址不能修改 2.final str = “aa”; str = "bb";/......

qimh
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部