內容觀察者ContentObserver類詳解

ContentObserver——內容觀察者,目的是觀察(捕捉)特定Uri引發的數據庫的變化,繼而作一些相應的處理,它相似於數據庫

   數據庫技術中的觸發器(Trigger),當ContentObserver所觀察的Uri發生變化時,便會觸發它。觸發器分爲表觸發器、行觸發器,app

  相應地ContentObserver也分爲「表「ContentObserver、「行」ContentObserver,固然這是與它所監聽的Uri MIME Type有關的。ide

 

           熟悉Content Provider(內容提供者)的應該知道,咱們能夠經過UriMatcher類註冊不一樣類型的Uri,咱們能夠經過這些不一樣的ui

    Uri來查詢不一樣的結果。根據Uri返回的結果,Uri Type能夠分爲:返回多條數據的Uri、返回單條數據的Uri。this

 

 

  註冊/取消註冊ContentObserver方法,抽象類ContentResolver類中的方法原型以下:spa

 

    public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)線程

             功能:爲指定的Uri註冊一個ContentObserver派生類實例,當給定的Uri發生改變時,回調該實例對象去處理。rest

             參數:uri          須要觀察的Uri(須要在UriMatcher裏註冊,不然該Uri也沒有意義了)orm

                        notifyForDescendents  爲false 表示精確匹配,即只匹配該Uriserver

                                                                     爲true 表示能夠同時匹配其派生的Uri,舉例以下:

                          假設UriMatcher 裏註冊的Uri共有一下類型:

                                1 、content://com.qin.cb/student (學生)

                                2 、content://com.qin.cb/student/# 

                                三、 content://com.qin.cb/student/schoolchild(小學生,派生的Uri)

 

                    假設咱們當前須要觀察的Uri爲content://com.qin.cb/student,若是發生數據變化的 Uri 爲   

           content://com.qin.cb/student/schoolchild ,當notifyForDescendents爲 false,那麼該ContentObserver會監聽不到,  

           可是當notifyForDescendents 爲ture,能捕捉該Uri的數據庫變化。

 

                     observer       ContentObserver的派生類實例

 

 

    public final void  unregisterContentObserver(ContentObserver observer)

          功能:取消對給定Uri的觀察

          參數: observer ContentObserver的派生類實例

 

        

ContentObserver類介紹

 

  構造方法 public void ContentObserver(Handler handler)  

                       說明:全部   ContentObserver的派生類都須要調用該構造方法

        參數: handler  Handler對象。能夠是主線程Handler(這時候能夠更新UI 了),也能夠是任何Handler對象。

 經常使用方法

   void onChange(boolean selfChange)

       功能:當觀察到的Uri發生變化時,回調該方法去處理。全部ContentObserver的派生類都須要重載該方法去處理邏輯。

       參數:selfChange 回調後,其值通常爲false,該參數意義不大(我也不懂,理解方法最重要)。

 

  另外兩個方法,用處不大,我也不懂,你們參照SDK自行理解,冒昧了。

  boolean  deliverSelfNotifications()

     說明:Returns true if this observer is interested in notifications for changes made through the cursor the observer is registered with.

  

  final void dispatchChange(boolean selfChange)

 

 

  觀察特定Uri的步驟以下

 

     一、    建立咱們特定的ContentObserver派生類,必須重載父類構造方法,必須重載onChange()方法去處理回調後的功能實現

     二、    利用context.getContentResolover()得到ContentResolove對象,接着調用registerContentObserver()方法去註冊內容觀察者

     三、    因爲ContentObserver的生命週期不一樣步於Activity和Service等,所以,在不須要時,須要手動的調用

             unregisterContentObserver()去取消註冊。    

 

若是ContentProvider的訪問者須要知道ContentProvider中的數據發生了變化,能夠在ContentProvider 發生數據變化時調用getContentResolver().notifyChange(uri, null)來通知註冊在此URI上的訪問者,例子以下:

public class PersonContentProvider extends ContentProvider {

public Uri insert(Uri uri, ContentValues values) {

       db.insert("person", "personid", values);

       getContext().getContentResolver().notifyChange(uri, null);

}

}

若是ContentProvider的訪問者須要獲得數據變化通知,必須使用ContentObserver對數據(數據採用uri描述)進行監聽,當監聽到數據變化通知時,系統就會調用ContentObserveronChange()方法:

getContentResolver().registerContentObserver(Uri.parse("content://cn.itcast.providers.personprovider/person"),

                      true, new PersonObserver(new Handler()));

public class PersonObserver extends ContentObserver{

       public PersonObserver(Handler handler) {

              super(handler);

      }

       public void onChange(boolean selfChange) {

           //此處能夠進行相應的業務處理

       }

}

 

l       竊聽用戶發出的短信

用戶使用系統自帶的短信程序發送短信,程序會經過ContentProvider把短信保存進數據庫,而且發出一個數據變化通知,使用ContentObserver對數據變化進行監聽,在用戶發送短信時,就會被ContentObserver竊聽到短信:

註冊監聽:

getContentResolver().registerContentObserver(Uri.parse("content://sms"),  true, new SmsObserver(new Handler()));

監聽類:

private final class SmsObserver extends ContentObserver{

       public SmsObserver(Handler handler) {

              super(handler);

       }

       public void onChange(boolean selfChange) {//查詢發送箱中的短信(處於正在發送狀態的短信放在發送箱)

              Cursor cursor = getContentResolver().query(Uri.parse("content://sms/outbox"),null, null, null, null);

              while(cursor.moveToNext()){

                     StringBuilder sb = new StringBuilder();

                     sb.append("_id=").append(cursor.getInt(cursor.getColumnIndex("_id")));

                     sb.append(",address=").append(cursor.getString(cursor.getColumnIndex("address")));

                     sb.append(";body=").append(cursor.getString(cursor.getColumnIndex("body")));

                     sb.append(";time=").append(cursor.getLong(cursor.getColumnIndex("date")));

                     Log.i("ReceiveSendSMS", sb.toString());

                    } }   

相關文章
相關標籤/搜索