歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android ContentObserver使用

Android ContentObserver使用

日期:2017/3/1 9:56:35   编辑:Linux編程

想象一個場景: 有個TextView, 用來顯示數據庫一個表的數據總數. 用戶通過UI界面對數據進行CRUD的操作. 這個TextView如何實時監控並更新顯示數據總數?

目錄:

第一節 ContentObserver的感性認識

第二節 3個重點

第三節 具體實現

這裡比較便捷且高效的方案是使用ContentObserver. 前提是已經建立了ContentProvider的支持. 先分析了一些網上廣為流傳了一個監控SMS變化的Observer例子. 畫個圖便於ContentObserver的感性認識.


通過這個圖, 主要了解3點就可以:

1, 建立繼承自ContentObserver的對象,實現其onChange()方法.

2, 在目標Activity中注冊和解除.

3, 在UI線程中, 用Handler接收來自Observer發出的Message, 更新UI.

思路有了, 就看具體的實現了.


一. 首先是建立一個繼承自ContentObserver的對象.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class TAGContentObserver extends ContentObserver{ private Context mContext; private Handler mHandler; public static final int TAG_DB_CHANGE = 921; public TAGContentObserver(Context context, Handler handler) { super(handler); mContext = context; mHandler = handler; } @Override public void onChange(boolean selfChange) { //數據變化, 重新查詢最新結果. Cursor cursor = mContext.getContentResolver().query(TAGDBOpenHelper.CONTENT_URI, null, null, null, null); //發送Message. 此Handler定義在Activity中, 拆開Message得到結果更新TextView. mHandler.obtainMessage(TAG_DB_CHANGE, cursor.getCount(), 0).sendToTarget(); } }

重點是實現其onChange()方法, 如注釋所寫. onChange可以理解為在得到數據變化的通知之後, Observer做的事情. 此例子中是重新查詢表的數據總數.


二. 在Activity中注冊和解除.

1 2 3 //注冊觀察者 ContentObserver observer = new TAGContentObserver(MainActivity.this, mMyHandler); getContentResolver().registerContentObserver(TAGDBOpenHelper.CONTENT_URI, true, observer);

1 2 //解除觀察者 getContentResolver().unregisterContentObserver(observer);

注冊和解除可以根據需要, 比如分別放在Activity的onCreate()和onDestroy()方法中. 關於這個CONTENT_URI, 是自定義的, 如:

1 2 3 public static final String TABLE_NAME_TAG = "tag"; public static final String AUTHORITY = "com.lichen.tagprovider"; public static final Uri CONTENT_URI = Uri.parse("content://"+TAGDBOpenHelper.AUTHORITY+"/"+TABLE_NAME_TAG);

此Observer的目的可以說是監聽或者觀察這個URI的變化.


三. 在UI線程中, 用Handler接收來自Observer發出的Message, 更新UI.

1 2 3 4 5 6 7 8 9 @Override public void handleMessage(Message msg) { switch (msg.what) { case TAGContentObserver.TAG_DB_CHANGE: TextView tagNum = (TextView) findViewById(R.id.tag_total_num); tagNum.setText("TAG總數: " + msg.arg1); break; } }

到這裡, 注冊觀察者Observer, 數據變化後重新查詢數據庫, 得到結果異步用Handler來更新UI. 看起來好像齊全了, 其實還有誰在什麼時候通知觀察者數據變化了的問題.


四. 在ContentProvider中添加通知數據變化.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 @Override public Uri insert(Uri uri, ContentValues values) { db = dbHelper.getWritableDatabase(); long rowId = db.insert(TAGDBOpenHelper.TABLE_NAME_TAG, "", values); if (rowId > 0) { Uri newUrl = ContentUris.withAppendedId(TAGDBOpenHelper.CONTENT_URI, rowId); //通知數據變化 getContext().getContentResolver().notifyChange(newUrl, null); return newUrl; } return null; } @Override public int delete(Uri uri, String where, String[] whereArgs) { db = dbHelper.getWritableDatabase(); int count = 0; switch (matcher.match(uri)) { case TAGDBOpenHelper.TAG: count = db.delete(TAGDBOpenHelper.TABLE_NAME_TAG, where, whereArgs); break; case TAGDBOpenHelper.TAG_ID: long parseId = ContentUris.parseId(uri); where = " _id = " + parseId ; count = db.delete(TAGDBOpenHelper.TABLE_NAME_TAG, where, null); break; } //通知數據變化 getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { db = dbHelper.getReadableDatabase(); int match = matcher.match(uri); Cursor cursor = null; switch (match) { case TAGDBOpenHelper.TAG: cursor = db.query(TAGDBOpenHelper.TABLE_NAME_TAG, null, null, null, null, null, null); cursor.setNotificationUri(getContext().getContentResolver(), uri);//通知數據變化 break; } return cursor; }

這樣, 這個TextView就可以實時監控並更新顯示數據總數了.

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved