|
17 | 17 | package android.app; |
18 | 18 |
|
19 | 19 | import android.content.Loader; |
| 20 | +import android.content.Loader.OnLoadCanceledListener; |
20 | 21 | import android.os.Bundle; |
21 | 22 | import android.util.DebugUtils; |
22 | 23 | import android.util.Log; |
@@ -219,7 +220,8 @@ class LoaderManagerImpl extends LoaderManager { |
219 | 220 |
|
220 | 221 | boolean mCreatingLoader; |
221 | 222 |
|
222 | | - final class LoaderInfo implements Loader.OnLoadCompleteListener<Object> { |
| 223 | + final class LoaderInfo implements Loader.OnLoadCompleteListener<Object>, |
| 224 | + Loader.OnLoadCanceledListener<Object> { |
223 | 225 | final int mId; |
224 | 226 | final Bundle mArgs; |
225 | 227 | LoaderManager.LoaderCallbacks<Object> mCallbacks; |
@@ -271,6 +273,7 @@ void start() { |
271 | 273 | } |
272 | 274 | if (!mListenerRegistered) { |
273 | 275 | mLoader.registerListener(mId, this); |
| 276 | + mLoader.registerOnLoadCanceledListener(this); |
274 | 277 | mListenerRegistered = true; |
275 | 278 | } |
276 | 279 | mLoader.startLoading(); |
@@ -329,11 +332,21 @@ void stop() { |
329 | 332 | // Let the loader know we're done with it |
330 | 333 | mListenerRegistered = false; |
331 | 334 | mLoader.unregisterListener(this); |
| 335 | + mLoader.unregisterOnLoadCanceledListener(this); |
332 | 336 | mLoader.stopLoading(); |
333 | 337 | } |
334 | 338 | } |
335 | 339 | } |
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 | + |
337 | 350 | void destroy() { |
338 | 351 | if (DEBUG) Log.v(TAG, " Destroying: " + this); |
339 | 352 | mDestroyed = true; |
@@ -361,15 +374,46 @@ void destroy() { |
361 | 374 | if (mListenerRegistered) { |
362 | 375 | mListenerRegistered = false; |
363 | 376 | mLoader.unregisterListener(this); |
| 377 | + mLoader.unregisterOnLoadCanceledListener(this); |
364 | 378 | } |
365 | 379 | mLoader.reset(); |
366 | 380 | } |
367 | 381 | if (mPendingLoader != null) { |
368 | 382 | mPendingLoader.destroy(); |
369 | 383 | } |
370 | 384 | } |
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) { |
373 | 417 | if (DEBUG) Log.v(TAG, "onLoadComplete: " + this); |
374 | 418 |
|
375 | 419 | if (mDestroyed) { |
@@ -632,7 +676,9 @@ public <D> Loader<D> restartLoader(int id, Bundle args, LoaderManager.LoaderCall |
632 | 676 | } else { |
633 | 677 | // Now we have three active loaders... we'll queue |
634 | 678 | // 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(); |
636 | 682 | if (info.mPendingLoader != null) { |
637 | 683 | if (DEBUG) Log.v(TAG, " Removing pending loader: " + info.mPendingLoader); |
638 | 684 | info.mPendingLoader.destroy(); |
|
0 commit comments