android 中的 ContentObserver (一)

文章出处:http://blog.csdn.net/shift_wwx/article/details/48736813

请转载的朋友标明出处~~


前言:最近碰到了ContentObserver,网上搜了一下没有找到详细的解释,小结一下。这一篇先来说一下基本用法。


我们知道,在db 做insert、delete等操作的时候,db会改变,这个时候UI 可能是需要更新的,那怎么才能知道db 是有了变化呢?不能做个监听一直查询db是否变化吧?这样就太废精力了,android 中提供了ContentObserver来作为db 数据变化后的callback。


随便找个例子(取于TvProvider):

    private Uri insertChannel(Uri uri, ContentValues values) {
        // Mark the owner package of this channel.
        values.put(Channels.COLUMN_PACKAGE_NAME, getCallingPackage_());

        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        long rowId = db.insert(CHANNELS_TABLE, null, values);
        if (rowId > 0) {
            Uri channelUri = TvContract.buildChannelUri(rowId);
            notifyChange(channelUri);
            return channelUri;
        }

        throw new SQLException("Failed to insert row into " + uri);
    }

values 是传进来的,一开始设置了一下package name,然后根据rowId找到 uri,最后调用notifyChange 这个 uri。

    private void notifyChange(Uri uri) {
        final Set batchNotifications = getBatchNotificationsSet();
        if (batchNotifications != null) {
            batchNotifications.add(uri);
        } else {
            getContext().getContentResolver().notifyChange(uri, null);
        }
    }
会通过ContentResolver 来调用 notifyChange,第二个参数是null,也就是说ContentObserver 是需要例外注册的。


在UI中可以注册:

    private void init() {
        ContentObserver ob = new ChannelObserver();
        mContext.getContentResolver().registerContentObserver(Channels.CONTENT_URI, true, ob);
    }
需要注意的是第二个参数,如果是false 的话,注册的observer 是不会被调用的,这里必须要为 true。

第一个参数是需要观察的表名,第三个是ContentObserver。


当然在不用的时候取消掉观察:

mContext.getContentResolver().unregisterContentObserver(mChannelObserver);
参数就是之前注册的的 observer了。

剩下就是ContentObserver 的实现了,为什么说实现?

public abstract class ContentObserver {
他是一个抽象类,没办法实例,只好继承,实现其中重要的方法。

    private final class ChannelObserver extends ContentObserver {

        public ChannelObserver() {
            super(new Handler());
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            updateChannelList();
        }

        @Override
        public IContentObserver releaseContentObserver() {
            // TODO Auto-generated method stub
            return super.releaseContentObserver();
        }

    }
首先是构造函数,需要传入Handler,可以通过handler 做些小事情,更新UI 什么的。当然不想用的话,弄个null 也是没问题的。

主要是需要实现onChange,db 更新后最终调用到这里,来更新UI 或者做一下更新的事情。


这一篇就先根据例子做一下简单的说明,这样功能就可以实现了,下一篇将结合 android 的 source code,分析更新的整个流程。请看 android中的ContentObserver(二)






你可能感兴趣的:(android,----,db)