diff options
author | Jeff Brown <jeffbrown@google.com> | 2012-01-23 13:01:18 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2012-01-23 13:01:18 -0800 |
commit | 86de0590b94bcce27e3038c27464bed510bb564a (patch) | |
tree | 0f192948c6ed5b80d4efd0219bd6c6b74b12ced9 /core/java/android/database | |
parent | bd4c9f13022e875c8b420248214482a5f5b46618 (diff) | |
download | frameworks_base-86de0590b94bcce27e3038c27464bed510bb564a.zip frameworks_base-86de0590b94bcce27e3038c27464bed510bb564a.tar.gz frameworks_base-86de0590b94bcce27e3038c27464bed510bb564a.tar.bz2 |
Clean up content observer code.
Improved the documentation a little bit.
Fixed a bug in ContentService wherein if a ContentObserver was
passed as an argument and its deliverSelfNotifications() method
returned true, then notifyChange would tell all observers that
the change was a self-change even though it was only a self-change
from the perspective of the provided observer.
Deprecated ContentObservable.notifyChange since it is never
used and in general it shouldn't be because we want the notification
to be posted to the handler.
Change-Id: Idde49eb40777e011a068f2adae8a32f779dfb923
Diffstat (limited to 'core/java/android/database')
-rw-r--r-- | core/java/android/database/ContentObservable.java | 28 | ||||
-rw-r--r-- | core/java/android/database/ContentObserver.java | 126 | ||||
-rw-r--r-- | core/java/android/database/DataSetObservable.java | 15 | ||||
-rw-r--r-- | core/java/android/database/Observable.java | 13 |
4 files changed, 103 insertions, 79 deletions
diff --git a/core/java/android/database/ContentObservable.java b/core/java/android/database/ContentObservable.java index 8d7b7c5..aece904 100644 --- a/core/java/android/database/ContentObservable.java +++ b/core/java/android/database/ContentObservable.java @@ -17,20 +17,28 @@ package android.database; /** - * A specialization of Observable for ContentObserver that provides methods for - * invoking the various callback methods of ContentObserver. + * A specialization of {@link Observable} for {@link ContentObserver} + * that provides methods for sending notifications to a list of + * {@link ContentObserver} objects. */ public class ContentObservable extends Observable<ContentObserver> { - + // Even though the generic method defined in Observable would be perfectly + // fine on its own, we can't delete this overridden method because it would + // potentially break binary compatibility with existing applications. @Override public void registerObserver(ContentObserver observer) { super.registerObserver(observer); } /** - * invokes dispatchUpdate on each observer, unless the observer doesn't want - * self-notifications and the update is from a self-notification - * @param selfChange + * Invokes {@link ContentObserver#dispatchChange} on each observer. + * + * If <code>selfChange</code> is true, only delivers the notification + * to the observer if it has indicated that it wants to receive self-change + * notifications by implementing {@link ContentObserver#deliverSelfNotifications} + * to return true. + * + * @param selfChange True if this is a self-change notification. */ public void dispatchChange(boolean selfChange) { synchronized(mObservers) { @@ -43,9 +51,13 @@ public class ContentObservable extends Observable<ContentObserver> { } /** - * invokes onChange on each observer - * @param selfChange + * Invokes {@link ContentObserver#onChange} on each observer. + * + * @param selfChange True if this is a self-change notification. + * + * @deprecated Use {@link #dispatchChange} instead. */ + @Deprecated public void notifyChange(boolean selfChange) { synchronized(mObservers) { for (ContentObserver observer : mObservers) { diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java index 3b829a3..4c20262 100644 --- a/core/java/android/database/ContentObserver.java +++ b/core/java/android/database/ContentObserver.java @@ -19,62 +19,19 @@ package android.database; import android.os.Handler; /** - * Receives call backs for changes to content. Must be implemented by objects which are added - * to a {@link ContentObservable}. + * Receives call backs for changes to content. + * Must be implemented by objects which are added to a {@link ContentObservable}. */ public abstract class ContentObserver { + private final Object mLock = new Object(); + private Transport mTransport; // guarded by mLock - private Transport mTransport; - - // Protects mTransport - private Object lock = new Object(); - - /* package */ Handler mHandler; - - private final class NotificationRunnable implements Runnable { - - private boolean mSelf; - - public NotificationRunnable(boolean self) { - mSelf = self; - } - - public void run() { - ContentObserver.this.onChange(mSelf); - } - } - - private static final class Transport extends IContentObserver.Stub { - ContentObserver mContentObserver; - - public Transport(ContentObserver contentObserver) { - mContentObserver = contentObserver; - } - - public boolean deliverSelfNotifications() { - ContentObserver contentObserver = mContentObserver; - if (contentObserver != null) { - return contentObserver.deliverSelfNotifications(); - } - return false; - } - - public void onChange(boolean selfChange) { - ContentObserver contentObserver = mContentObserver; - if (contentObserver != null) { - contentObserver.dispatchChange(selfChange); - } - } - - public void releaseContentObserver() { - mContentObserver = null; - } - } + Handler mHandler; /** - * onChange() will happen on the provider Handler. + * Creates a content observer. * - * @param handler The handler to run {@link #onChange} on. + * @param handler The handler to run {@link #onChange} on, or null if none. */ public ContentObserver(Handler handler) { mHandler = handler; @@ -86,7 +43,7 @@ public abstract class ContentObserver { * {@hide} */ public IContentObserver getContentObserver() { - synchronized(lock) { + synchronized (mLock) { if (mTransport == null) { mTransport = new Transport(this); } @@ -101,8 +58,8 @@ public abstract class ContentObserver { * {@hide} */ public IContentObserver releaseContentObserver() { - synchronized(lock) { - Transport oldTransport = mTransport; + synchronized (mLock) { + final Transport oldTransport = mTransport; if (oldTransport != null) { oldTransport.releaseContentObserver(); mTransport = null; @@ -112,22 +69,36 @@ public abstract class ContentObserver { } /** - * Returns true if this observer is interested in notifications for changes - * made through the cursor the observer is registered with. + * Returns true if this observer is interested receiving self-change notifications. + * + * Subclasses should override this method to indicate whether the observer + * is interested in receiving notifications for changes that it made to the + * content itself. + * + * @return True if self-change notifications should be delivered to the observer. */ public boolean deliverSelfNotifications() { return false; } /** - * This method is called when a change occurs to the cursor that - * is being observed. - * - * @param selfChange true if the update was caused by a call to <code>commit</code> on the - * cursor that is being observed. + * This method is called when a content change occurs. + * + * @param selfChange True if this is a self-change notification. */ - public void onChange(boolean selfChange) {} + public void onChange(boolean selfChange) { + // Do nothing. Subclass should override. + } + /** + * Dispatches a change notification to the observer. + * + * If a {@link Handler} was supplied to the {@link ContentObserver} constructor, + * then a call to the {@link #onChange} method is posted to the handler's message queue. + * Otherwise, the {@link #onChange} method is invoked immediately on this thread. + * + * @param selfChange True if this is a self-change notification. + */ public final void dispatchChange(boolean selfChange) { if (mHandler == null) { onChange(selfChange); @@ -135,4 +106,37 @@ public abstract class ContentObserver { mHandler.post(new NotificationRunnable(selfChange)); } } + + private final class NotificationRunnable implements Runnable { + private final boolean mSelf; + + public NotificationRunnable(boolean self) { + mSelf = self; + } + + @Override + public void run() { + ContentObserver.this.onChange(mSelf); + } + } + + private static final class Transport extends IContentObserver.Stub { + private ContentObserver mContentObserver; + + public Transport(ContentObserver contentObserver) { + mContentObserver = contentObserver; + } + + @Override + public void onChange(boolean selfChange) { + ContentObserver contentObserver = mContentObserver; + if (contentObserver != null) { + contentObserver.dispatchChange(selfChange); + } + } + + public void releaseContentObserver() { + mContentObserver = null; + } + } } diff --git a/core/java/android/database/DataSetObservable.java b/core/java/android/database/DataSetObservable.java index 51c72c1..ca77a13 100644 --- a/core/java/android/database/DataSetObservable.java +++ b/core/java/android/database/DataSetObservable.java @@ -17,13 +17,15 @@ package android.database; /** - * A specialization of Observable for DataSetObserver that provides methods for - * invoking the various callback methods of DataSetObserver. + * A specialization of {@link Observable} for {@link DataSetObserver} + * that provides methods for sending notifications to a list of + * {@link DataSetObserver} objects. */ public class DataSetObservable extends Observable<DataSetObserver> { /** - * Invokes onChanged on each observer. Called when the data set being observed has - * changed, and which when read contains the new state of the data. + * Invokes {@link DataSetObserver#onChanged} on each observer. + * Called when the contents of the data set have changed. The recipient + * will obtain the new contents the next time it queries the data set. */ public void notifyChanged() { synchronized(mObservers) { @@ -38,8 +40,9 @@ public class DataSetObservable extends Observable<DataSetObserver> { } /** - * Invokes onInvalidated on each observer. Called when the data set being monitored - * has changed such that it is no longer valid. + * Invokes {@link DataSetObserver#onInvalidated} on each observer. + * Called when the data set is no longer valid and cannot be queried again, + * such as when the data set has been closed. */ public void notifyInvalidated() { synchronized (mObservers) { diff --git a/core/java/android/database/Observable.java b/core/java/android/database/Observable.java index b6fecab..aff32db 100644 --- a/core/java/android/database/Observable.java +++ b/core/java/android/database/Observable.java @@ -19,7 +19,12 @@ package android.database; import java.util.ArrayList; /** - * Provides methods for (un)registering arbitrary observers in an ArrayList. + * Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}. + * + * This abstract class is intended to be subclassed and specialized to maintain + * a registry of observers of specific types and dispatch notifications to them. + * + * @param T The observer type. */ public abstract class Observable<T> { /** @@ -66,13 +71,13 @@ public abstract class Observable<T> { mObservers.remove(index); } } - + /** - * Remove all registered observer + * Remove all registered observers. */ public void unregisterAll() { synchronized(mObservers) { mObservers.clear(); - } + } } } |