實現ContentProvider事務操做以及對數據庫的監控

    對數據庫的操做,咱們常常避免不了進行事務處理,這樣能夠減小對數據庫操做的次數,從而提升了讀寫數據庫的效率。以前博主對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());
……
相關文章
相關標籤/搜索