Skip to content

Commit b19a71a

Browse files
author
Jeff Brown
committed
Support automatic cancellation of Loaders.
Change-Id: I18d3f49e413f48fcdd519d15e99c238ad54d35b9
1 parent f10d69f commit b19a71a

File tree

6 files changed

+267
-60
lines changed

6 files changed

+267
-60
lines changed

api/current.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4660,10 +4660,9 @@ package android.content {
46604660

46614661
public abstract class AsyncTaskLoader extends android.content.Loader {
46624662
ctor public AsyncTaskLoader(android.content.Context);
4663-
method public boolean cancelLoad();
4664-
method protected boolean isLoadInBackgroundCanceled();
4663+
method public void cancelLoadInBackground();
4664+
method public boolean isLoadInBackgroundCanceled();
46654665
method public abstract D loadInBackground();
4666-
method protected void onCancelLoadInBackground();
46674666
method public void onCanceled(D);
46684667
method protected D onLoadInBackground();
46694668
method public void setUpdateThrottle(long);
@@ -5754,7 +5753,9 @@ package android.content {
57545753
public class Loader {
57555754
ctor public Loader(android.content.Context);
57565755
method public void abandon();
5756+
method public boolean cancelLoad();
57575757
method public java.lang.String dataToString(D);
5758+
method public void deliverCancellation();
57585759
method public void deliverResult(D);
57595760
method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
57605761
method public void forceLoad();
@@ -5764,23 +5765,30 @@ package android.content {
57645765
method public boolean isReset();
57655766
method public boolean isStarted();
57665767
method protected void onAbandon();
5768+
method protected boolean onCancelLoad();
57675769
method public void onContentChanged();
57685770
method protected void onForceLoad();
57695771
method protected void onReset();
57705772
method protected void onStartLoading();
57715773
method protected void onStopLoading();
57725774
method public void registerListener(int, android.content.Loader.OnLoadCompleteListener<D>);
5775+
method public void registerOnLoadCanceledListener(android.content.Loader.OnLoadCanceledListener<D>);
57735776
method public void reset();
57745777
method public final void startLoading();
57755778
method public void stopLoading();
57765779
method public boolean takeContentChanged();
57775780
method public void unregisterListener(android.content.Loader.OnLoadCompleteListener<D>);
5781+
method public void unregisterOnLoadCanceledListener(android.content.Loader.OnLoadCanceledListener<D>);
57785782
}
57795783

57805784
public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
57815785
ctor public Loader.ForceLoadContentObserver();
57825786
}
57835787

5788+
public static abstract interface Loader.OnLoadCanceledListener {
5789+
method public abstract void onLoadCanceled(android.content.Loader<D>);
5790+
}
5791+
57845792
public static abstract interface Loader.OnLoadCompleteListener {
57855793
method public abstract void onLoadComplete(android.content.Loader<D>, D);
57865794
}

core/java/android/app/LoaderManager.java

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package android.app;
1818

1919
import android.content.Loader;
20+
import android.content.Loader.OnLoadCanceledListener;
2021
import android.os.Bundle;
2122
import android.util.DebugUtils;
2223
import android.util.Log;
@@ -219,7 +220,8 @@ class LoaderManagerImpl extends LoaderManager {
219220

220221
boolean mCreatingLoader;
221222

222-
final class LoaderInfo implements Loader.OnLoadCompleteListener<Object> {
223+
final class LoaderInfo implements Loader.OnLoadCompleteListener<Object>,
224+
Loader.OnLoadCanceledListener<Object> {
223225
final int mId;
224226
final Bundle mArgs;
225227
LoaderManager.LoaderCallbacks<Object> mCallbacks;
@@ -271,6 +273,7 @@ void start() {
271273
}
272274
if (!mListenerRegistered) {
273275
mLoader.registerListener(mId, this);
276+
mLoader.registerOnLoadCanceledListener(this);
274277
mListenerRegistered = true;
275278
}
276279
mLoader.startLoading();
@@ -329,11 +332,21 @@ void stop() {
329332
// Let the loader know we're done with it
330333
mListenerRegistered = false;
331334
mLoader.unregisterListener(this);
335+
mLoader.unregisterOnLoadCanceledListener(this);
332336
mLoader.stopLoading();
333337
}
334338
}
335339
}
336-
340+
341+
void cancel() {
342+
if (DEBUG) Log.v(TAG, " Canceling: " + this);
343+
if (mStarted && mLoader != null && mListenerRegistered) {
344+
if (!mLoader.cancelLoad()) {
345+
onLoadCanceled(mLoader);
346+
}
347+
}
348+
}
349+
337350
void destroy() {
338351
if (DEBUG) Log.v(TAG, " Destroying: " + this);
339352
mDestroyed = true;
@@ -361,15 +374,46 @@ void destroy() {
361374
if (mListenerRegistered) {
362375
mListenerRegistered = false;
363376
mLoader.unregisterListener(this);
377+
mLoader.unregisterOnLoadCanceledListener(this);
364378
}
365379
mLoader.reset();
366380
}
367381
if (mPendingLoader != null) {
368382
mPendingLoader.destroy();
369383
}
370384
}
371-
372-
@Override public void onLoadComplete(Loader<Object> loader, Object data) {
385+
386+
@Override
387+
public void onLoadCanceled(Loader<Object> loader) {
388+
if (DEBUG) Log.v(TAG, "onLoadCanceled: " + this);
389+
390+
if (mDestroyed) {
391+
if (DEBUG) Log.v(TAG, " Ignoring load canceled -- destroyed");
392+
return;
393+
}
394+
395+
if (mLoaders.get(mId) != this) {
396+
// This cancellation message is not coming from the current active loader.
397+
// We don't care about it.
398+
if (DEBUG) Log.v(TAG, " Ignoring load canceled -- not active");
399+
return;
400+
}
401+
402+
LoaderInfo pending = mPendingLoader;
403+
if (pending != null) {
404+
// There is a new request pending and we were just
405+
// waiting for the old one to cancel or complete before starting
406+
// it. So now it is time, switch over to the new loader.
407+
if (DEBUG) Log.v(TAG, " Switching to pending loader: " + pending);
408+
mPendingLoader = null;
409+
mLoaders.put(mId, null);
410+
destroy();
411+
installLoader(pending);
412+
}
413+
}
414+
415+
@Override
416+
public void onLoadComplete(Loader<Object> loader, Object data) {
373417
if (DEBUG) Log.v(TAG, "onLoadComplete: " + this);
374418

375419
if (mDestroyed) {
@@ -632,7 +676,9 @@ public <D> Loader<D> restartLoader(int id, Bundle args, LoaderManager.LoaderCall
632676
} else {
633677
// Now we have three active loaders... we'll queue
634678
// up this request to be processed once one of the other loaders
635-
// finishes.
679+
// finishes or is canceled.
680+
if (DEBUG) Log.v(TAG, " Current loader is running; attempting to cancel");
681+
info.cancel();
636682
if (info.mPendingLoader != null) {
637683
if (DEBUG) Log.v(TAG, " Removing pending loader: " + info.mPendingLoader);
638684
info.mPendingLoader.destroy();

0 commit comments

Comments
 (0)