From e5552be22a016dd8b79026f56b071ab128d5a904 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Wed, 27 Apr 2016 10:42:19 -0700 Subject: [PATCH] Fix a bug where restartLoader would result in a stuck loader Framework edition In some cases restartLoader calls that happen in quick succession could cause the new loader to become stuck and never run. Treat loader restarts for loaders that have not yet started the same as starting a brand new loader. Bug 27437287 https://code.google.com/p/android/issues/detail?id=56464 Change-Id: Ia4e276fc8e63d43b9c52c6155cea827b194d8b19 --- core/java/android/app/LoaderManager.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java index f203f46f44083..c14dec93c348e 100644 --- a/core/java/android/app/LoaderManager.java +++ b/core/java/android/app/LoaderManager.java @@ -339,13 +339,16 @@ class LoaderManagerImpl extends LoaderManager { } } - void cancel() { + boolean cancel() { if (DEBUG) Log.v(TAG, " Canceling: " + this); if (mStarted && mLoader != null && mListenerRegistered) { - if (!mLoader.cancelLoad()) { + final boolean cancelLoadResult = mLoader.cancelLoad(); + if (!cancelLoadResult) { onLoadCanceled(mLoader); } + return cancelLoadResult; } + return false; } void destroy() { @@ -667,20 +670,21 @@ class LoaderManagerImpl extends LoaderManager { mInactiveLoaders.put(id, info); } else { // We already have an inactive loader for this ID that we are - // waiting for! What to do, what to do... - if (!info.mStarted) { - // The current Loader has not been started... we thus - // have no reason to keep it around, so bam, slam, - // thank-you-ma'am. + // waiting for! Try to cancel; if this returns true then the task is still + // running and we have more work to do. + if (!info.cancel()) { + // The current Loader has not been started or was successfully canceled, + // we thus have no reason to keep it around. Remove it and a new + // LoaderInfo will be created below. if (DEBUG) Log.v(TAG, " Current loader is stopped; replacing"); mLoaders.put(id, null); info.destroy(); } else { // Now we have three active loaders... we'll queue // up this request to be processed once one of the other loaders - // finishes or is canceled. - if (DEBUG) Log.v(TAG, " Current loader is running; attempting to cancel"); - info.cancel(); + // finishes. + if (DEBUG) Log.v(TAG, + " Current loader is running; configuring pending loader"); if (info.mPendingLoader != null) { if (DEBUG) Log.v(TAG, " Removing pending loader: " + info.mPendingLoader); info.mPendingLoader.destroy();