diff options
| author | 2011-01-09 11:05:50 -0800 | |
|---|---|---|
| committer | 2011-01-09 11:05:50 -0800 | |
| commit | 59d8edd09dc88cc0eb629bdee711a004d300f2fa (patch) | |
| tree | ae55a0c7a3f559dd2a2d12f891af9dde9787d363 | |
| parent | 2954cd91ab1fef14c8aed5173c160ce00558cd3a (diff) | |
Fixed the waitForLoader method.
The reason we need a separate latch is that
AsyncTask will post onPostExecute/onCancelled
_after_ executing mFuture.get(). The previous
implementation would only wait for mFuture.get()
to complete and not the entire task.
Change-Id: I96964591980965148eb09af38b5838bfa5d28277
| -rw-r--r-- | core/java/android/content/AsyncTaskLoader.java | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java index ec4e578725e9..98710558ce18 100644 --- a/core/java/android/content/AsyncTaskLoader.java +++ b/core/java/android/content/AsyncTaskLoader.java @@ -19,12 +19,11 @@ package android.content; import android.os.AsyncTask; import android.os.Handler; import android.os.SystemClock; -import android.util.Log; import android.util.TimeUtils; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.concurrent.ExecutionException; +import java.util.concurrent.CountDownLatch; /** * Abstract Loader that provides an {@link AsyncTask} to do the work. @@ -33,6 +32,7 @@ import java.util.concurrent.ExecutionException; */ public abstract class AsyncTaskLoader<D> extends Loader<D> { + private static final String TAG = "AsyncTaskLoader"; final class LoadTask extends AsyncTask<Void, Void, D> implements Runnable { @@ -40,6 +40,8 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> { D result; boolean waiting; + private CountDownLatch done = new CountDownLatch(1); + /* Runs on a worker thread */ @Override protected D doInBackground(Void... params) { @@ -50,12 +52,20 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> { /* Runs on the UI thread */ @Override protected void onPostExecute(D data) { - AsyncTaskLoader.this.dispatchOnLoadComplete(this, data); + try { + AsyncTaskLoader.this.dispatchOnLoadComplete(this, data); + } finally { + done.countDown(); + } } @Override protected void onCancelled() { - AsyncTaskLoader.this.dispatchOnCancelled(this, result); + try { + AsyncTaskLoader.this.dispatchOnCancelled(this, result); + } finally { + done.countDown(); + } } @Override @@ -209,7 +219,8 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> { /** * Locks the current thread until the loader completes the current load * operation. Returns immediately if there is no load operation running. - * Should not be called from the UI thread. + * Should not be called from the UI thread: calling it from the UI + * thread would cause a deadlock. * <p> * Use for testing only. <b>Never</b> call this from a UI thread. */ @@ -217,12 +228,9 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> { LoadTask task = mTask; if (task != null) { try { - task.get(); + task.done.await(); } catch (InterruptedException e) { - Log.w(TAG, e); - } catch (ExecutionException e) { - throw new RuntimeException("An error occured while executing waitForLoader()", - e.getCause()); + // Ignore } } } |