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