diff options
Diffstat (limited to 'core/java/android/content')
-rw-r--r-- | core/java/android/content/AsyncTaskLoader.java | 6 | ||||
-rw-r--r-- | core/java/android/content/CursorLoader.java | 44 | ||||
-rw-r--r-- | core/java/android/content/Loader.java | 138 |
3 files changed, 154 insertions, 34 deletions
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java index b19c072..30f8ffc 100644 --- a/core/java/android/content/AsyncTaskLoader.java +++ b/core/java/android/content/AsyncTaskLoader.java @@ -53,12 +53,8 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> { super(context); } - /** - * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously - * loaded data set and load a new one. - */ @Override - public void forceLoad() { + protected void onForceLoad() { cancelLoad(); mTask = new LoadTask(); mTask.execute((Void[]) null); diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java index 9e03c25..91dd23b 100644 --- a/core/java/android/content/CursorLoader.java +++ b/core/java/android/content/CursorLoader.java @@ -20,21 +20,25 @@ import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.Arrays; + /** * A loader that queries the {@link ContentResolver} and returns a {@link Cursor}. */ public class CursorLoader extends AsyncTaskLoader<Cursor> { - Cursor mCursor; - ForceLoadContentObserver mObserver; - boolean mStopped; - boolean mContentChanged; - boolean mReset; + final ForceLoadContentObserver mObserver; + Uri mUri; String[] mProjection; String mSelection; String[] mSelectionArgs; String mSortOrder; + Cursor mCursor; + boolean mContentChanged; + /* Runs on a worker thread */ @Override public Cursor loadInBackground() { @@ -69,7 +73,7 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> { Cursor oldCursor = mCursor; mCursor = cursor; - if (!mStopped) { + if (isStarted()) { super.deliverResult(cursor); } @@ -97,10 +101,7 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> { * Must be called from the UI thread */ @Override - public void startLoading() { - mStopped = false; - mReset = false; - + protected void onStartLoading() { if (mCursor != null) { deliverResult(mCursor); } @@ -114,17 +115,14 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> { * Must be called from the UI thread */ @Override - public void stopLoading() { + protected void onStopLoading() { // Attempt to cancel the current load task if possible. cancelLoad(); - - // Make sure that any outstanding loads clean themselves up properly - mStopped = true; } @Override public void onContentChanged() { - if (mStopped) { + if (!isStarted()) { // This loader has been stopped, so we don't want to load // new data right now... but keep track of it changing to // refresh later if we start again. @@ -142,7 +140,7 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> { } @Override - public void reset() { + protected void onReset() { mReset = true; // Ensure the loader is stopped @@ -193,4 +191,18 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> { public void setSortOrder(String sortOrder) { mSortOrder = sortOrder; } + + @Override + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mUri="); writer.println(mUri); + writer.print(prefix); writer.print("mProjection="); + writer.println(Arrays.toString(mProjection)); + writer.print(prefix); writer.print("mSelection="); writer.println(mSelection); + writer.print(prefix); writer.print("mSelectionArgs="); + writer.println(Arrays.toString(mSelectionArgs)); + writer.print(prefix); writer.print("mSortOrder="); writer.println(mSortOrder); + writer.print(prefix); writer.print("mCursor="); writer.println(mCursor); + writer.print(prefix); writer.print("mContentChanged="); writer.println(mContentChanged); + } } diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java index 73d7103..f425b29 100644 --- a/core/java/android/content/Loader.java +++ b/core/java/android/content/Loader.java @@ -18,18 +18,27 @@ package android.content; import android.database.ContentObserver; import android.os.Handler; +import android.util.DebugUtils; + +import java.io.FileDescriptor; +import java.io.PrintWriter; /** * An abstract class that performs asynchronous loading of data. While Loaders are active * they should monitor the source of their data and deliver new results when the contents * change. * + * <p>Subclasses generally must implement at least {@link #onStartLoading()}, + * {@link #onStopLoading()}, {@link #onForceLoad()}, and {@link #onReset()}. + * * @param <D> The result returned when the load is complete */ -public abstract class Loader<D> { +public class Loader<D> { int mId; OnLoadCompleteListener<D> mListener; Context mContext; + boolean mStarted = false; + boolean mReset = true; public final class ForceLoadContentObserver extends ContentObserver { public ForceLoadContentObserver() { @@ -122,28 +131,88 @@ public abstract class Loader<D> { } /** + * Return whether this load has been started. That is, its {@link #startLoading()} + * has been called and no calls to {@link #stopLoading()} or + * {@link #reset()} have yet been made. + */ + public boolean isStarted() { + return mStarted; + } + + /** + * Return whether this load has been reset. That is, either the loader + * has not yet been started for the first time, or its {@link #reset()} + * has been called. + */ + public boolean isReset() { + return mReset; + } + + /** * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks * will be called on the UI thread. If a previous load has been completed and is still valid * the result may be passed to the callbacks immediately. The loader will monitor the source of * the data set and may deliver future callbacks if the source changes. Calling * {@link #stopLoading} will stop the delivery of callbacks. * - * <p>Must be called from the UI thread + * <p>This updates the Loader's internal state so that + * {@link #isStarted()} and {@link #isReset()} will return the correct + * values, and then calls the implementation's {@link #onStartLoading()}. + * + * <p>Must be called from the UI thread. + */ + public void startLoading() { + mStarted = true; + mReset = false; + onStartLoading(); + } + + /** + * Subclasses must implement this to take care of loading their data, + * as per {@link #startLoading()}. This is not called by clients directly, + * but as a result of a call to {@link #startLoading()}. */ - public abstract void startLoading(); + protected void onStartLoading() { + } /** * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously - * loaded data set and load a new one. + * loaded data set and load a new one. This simply calls through to the + * implementation's {@link #onForceLoad()}. + * + * <p>Must be called from the UI thread. */ - public abstract void forceLoad(); + public void forceLoad() { + onForceLoad(); + } /** - * Stops delivery of updates until the next time {@link #startLoading()} is called + * Subclasses must implement this to take care of requests to {@link #forceLoad()}. + */ + protected void onForceLoad() { + } + + /** + * Stops delivery of updates until the next time {@link #startLoading()} is called. * - * <p>Must be called from the UI thread + * <p>This updates the Loader's internal state so that + * {@link #isStarted()} will return the correct + * value, and then calls the implementation's {@link #onStopLoading()}. + * + * <p>Must be called from the UI thread. */ - public abstract void stopLoading(); + public void stopLoading() { + mStarted = false; + onStopLoading(); + } + + /** + * Subclasses must implement this to take care of stopping their loader, + * as per {@link #stopLoading()}. This is not called by clients directly, + * but as a result of a call to {@link #stopLoading()}. + */ + protected void onStopLoading() { + } /** * Resets the state of the Loader. The Loader should at this point free @@ -151,17 +220,24 @@ public abstract class Loader<D> { * {@link #startLoading()} may later be called at which point it must be * able to start running again. * - * <p>Must be called from the UI thread + * <p>This updates the Loader's internal state so that + * {@link #isStarted()} and {@link #isReset()} will return the correct + * values, and then calls the implementation's {@link #onReset()}. + * + * <p>Must be called from the UI thread. */ public void reset() { - destroy(); + onReset(); + mReset = true; + mStarted = false; } /** - * @deprecated Old API, implement reset() now. + * Subclasses must implement this to take care of resetting their loader, + * as per {@link #reset()}. This is not called by clients directly, + * but as a result of a call to {@link #reset()}. */ - @Deprecated - public void destroy() { + protected void onReset() { } /** @@ -173,4 +249,40 @@ public abstract class Loader<D> { public void onContentChanged() { forceLoad(); } + + /** + * For debugging, converts an instance of the Loader's data class to + * a string that can be printed. Must handle a null data. + */ + public String dataToString(D data) { + StringBuilder sb = new StringBuilder(64); + DebugUtils.buildShortClassTag(data, sb); + sb.append("}"); + return sb.toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(64); + DebugUtils.buildShortClassTag(this, sb); + sb.append(" id="); + sb.append(mId); + sb.append("}"); + return sb.toString(); + } + + /** + * Print the Loader's state into the given stream. + * + * @param prefix Text to print at the front of each line. + * @param fd The raw file descriptor that the dump is being sent to. + * @param writer A PrintWriter to which the dump is to be set. + * @param args Additional arguments to the dump request. + */ + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + writer.print(prefix); writer.print("mId="); writer.print(mId); + writer.print(" mListener="); writer.println(mListener); + writer.print(prefix); writer.print("mStarted="); writer.print(mStarted); + writer.print(" mReset="); writer.println(mReset); + } }
\ No newline at end of file |