AbstractCursor.java檔案
/**
* This is an abstract cursor class that handles a lot of the common code
* that all cursors need to deal with and is provided for convenience reasons.
*/
public abstract class AbstractCursor implements CrossProcessCursor {
private static final String TAG = "Cursor";
DataSetObservable mDataSetObservable = new DataSetObservable();
ContentObservable mContentObservable = new ContentObservable();
-------------------省略------------------
public void deactivate() {
deactivateInternal();
}
/**
* @hide
*/
public void deactivateInternal() {
if (mSelfObserver != null) {
mContentResolver.unregisterContentObserver(mSelfObserver);
mSelfObserverRegistered = false;
}
mDataSetObservable.notifyInvalidated();
}
public boolean requery() {
if (mSelfObserver != null && mSelfObserverRegistered == false) {
mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver);
mSelfObserverRegistered = true;
}
mDataSetObservable.notifyChanged();
return true;
}
public boolean isClosed() {
return mClosed;
}
public void close() {
mClosed = true;
mContentObservable.unregisterAll();
deactivateInternal();
}
-------------------省略------------------
public void registerContentObserver(ContentObserver observer) {
mContentObservable.registerObserver(observer);
}
public void unregisterContentObserver(ContentObserver observer) {
// cursor will unregister all observers when it close
if (!mClosed) {
mContentObservable.unregisterObserver(observer);
}
}
/**
* This is hidden until the data set change model has been re-evaluated.
* @hide
*/
protected void notifyDataSetChange() {
mDataSetObservable.notifyChanged();
}
/**
* This is hidden until the data set change model has been re-evaluated.
* @hide
*/
protected DataSetObservable getDataSetObservable() {
return mDataSetObservable;
}
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
/**
* Subclasses must call this method when they finish committing updates to notify all
* observers.
*
* @param selfChange
*/
protected void onChange(boolean selfChange) {
synchronized (mSelfObserverLock) {
mContentObservable.dispatchChange(selfChange);
if (mNotifyUri != null && selfChange) {
mContentResolver.notifyChange(mNotifyUri, mSelfObserver);
}
}
}
/**
* Specifies a content URI to watch for changes.
*
* @param cr The content resolver from the caller's context.
* @param notifyUri The URI to watch for changes. This can be a
* specific row URI, or a base URI for a whole class of content.
*/
public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
synchronized (mSelfObserverLock) {
mNotifyUri = notifyUri;
mContentResolver = cr;
if (mSelfObserver != null) {
mContentResolver.unregisterContentObserver(mSelfObserver);
}
mSelfObserver = new SelfContentObserver(this);
mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver);
mSelfObserverRegistered = true;
}
}
-------------------省略------------------
@Override
protected void finalize() {
if (mSelfObserver != null && mSelfObserverRegistered == true) {
mContentResolver.unregisterContentObserver(mSelfObserver);
}
}
/**
* Cursors use this class to track changes others make to their URI.
*/
protected static class SelfContentObserver extends ContentObserver {
WeakReference<AbstractCursor> mCursor;
public SelfContentObserver(AbstractCursor cursor) {
super(null);
mCursor = new WeakReference<AbstractCursor>(cursor);
}
@Override
public boolean deliverSelfNotifications() {
return false;
}
@Override
public void onChange(boolean selfChange) {
AbstractCursor cursor = mCursor.get();
if (cursor != null) {
cursor.onChange(false);
}
}
}
-------------------省略------------------
protected ContentResolver mContentResolver;
protected boolean mClosed = false;
private Uri mNotifyUri;
private ContentObserver mSelfObserver;
final private Object mSelfObserverLock = new Object();
private boolean mSelfObserverRegistered;
}