Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2343)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/ntp/interests/InterestsItemView.java

Issue 1885463002: Create a Promise class to simplify dealing with async results. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove IntDef Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/interests/InterestsItemView.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/interests/InterestsItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/interests/InterestsItemView.java
index 62d11419d7f58557c773853c43167d28ce99fc0f..4484def7d18d02e7cff3a3a8565b751c800859bd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/interests/InterestsItemView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/interests/InterestsItemView.java
@@ -24,8 +24,9 @@ import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
+import org.chromium.base.Callback;
import org.chromium.base.Log;
-import org.chromium.base.ObserverList;
+import org.chromium.base.Promise;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.interests.InterestsPage.InterestsClickListener;
@@ -82,7 +83,7 @@ class InterestsItemView extends AppCompatTextView implements OnClickListener {
private final Context mContext;
private final DrawingData mDrawingData;
- private final LruCache<String, ImageHolder> mImageCache;
+ private final LruCache<String, Promise<Drawable>> mImageCache;
private final InterestsClickListener mListener;
/**
@@ -93,7 +94,7 @@ class InterestsItemView extends AppCompatTextView implements OnClickListener {
* @param drawingData Information about the view size.
*/
InterestsItemView(Context context, Interest interest, InterestsClickListener listener,
- LruCache<String, ImageHolder> imageCache, DrawingData drawingData) {
+ LruCache<String, Promise<Drawable>> imageCache, DrawingData drawingData) {
super(context);
mContext = context;
@@ -132,25 +133,32 @@ class InterestsItemView extends AppCompatTextView implements OnClickListener {
setText(mInterest.getName());
- ImageHolder holder = mImageCache.get(mInterest.getImageUrl());
- if (holder == null) {
- // Create a new holder, add it to the cache and set it downloading.
- holder = new ImageHolder();
- mImageCache.put(mInterest.getImageUrl(), holder);
- new ImageDownloadTask(mInterest.getImageUrl(), holder, getResources()).execute();
+ Promise<Drawable> promise = mImageCache.get(mInterest.getImageUrl());
+ if (promise == null) {
+ promise = new Promise<Drawable>();
+ mImageCache.put(mInterest.getImageUrl(),
+ ImageDownloadTask.start(mInterest.getImageUrl(), getResources()));
}
- if (holder.getImageDrawable() != null) {
- setImage(holder.getImageDrawable());
- } else {
- // Add a callback to a subclass that will call setImage once the holder is filled.
- holder.addListener(new ImageDownloadedCallback());
-
- // Display a letter tile in the meantime.
+ // If not fulfilled, display a letter tile while waiting for the image to download.
+ if (!promise.isFulfilled()) {
mDrawingData.mIconGenerator.setBackgroundColor(getTileColor(mInterest.getName()));
setImage(new BitmapDrawable(mContext.getResources(),
mDrawingData.mIconGenerator.generateIconForText(mInterest.getName())));
}
+
+ // Once fulfilled, display the image (unless this view has been repurposed for a different
+ // Interest).
+ final String urlWhenDownloadRequested = mInterest.getImageUrl();
+ promise.then(new Callback<Drawable>() {
+ @Override
+ public void onResult(Drawable drawable) {
+ if (drawable == null) return;
+ if (TextUtils.equals(mInterest.getImageUrl(), urlWhenDownloadRequested)) return;
+
+ setImage(drawable);
+ }
+ });
}
/**
@@ -184,17 +192,23 @@ class InterestsItemView extends AppCompatTextView implements OnClickListener {
}
/*
- * An AsyncTask that downloads an image, formats it then puts it in the given holder.
+ * An AsyncTask that downloads an image and formats it.
*/
private static class ImageDownloadTask extends AsyncTask<Void, Void, Drawable> {
+ public static Promise<Drawable> start(String url, Resources resources) {
+ Promise<Drawable> promise = new Promise<Drawable>();
+ new ImageDownloadTask(url, promise, resources).executeOnExecutor(THREAD_POOL_EXECUTOR);
+ return promise;
+ }
+
private final String mUrl;
- private final ImageHolder mImageHolder;
private final Resources mResources;
+ private Promise<Drawable> mPromise;
- public ImageDownloadTask(String url, ImageHolder holder, Resources resources) {
+ private ImageDownloadTask(String url, Promise<Drawable> promise, Resources resources) {
mUrl = url;
- mImageHolder = holder;
+ mPromise = promise;
mResources = resources;
}
@@ -221,60 +235,9 @@ class InterestsItemView extends AppCompatTextView implements OnClickListener {
@Override
protected void onPostExecute(Drawable image) {
- // This is run on the main thread.
- mImageHolder.set(image, mUrl);
- }
- }
-
- /*
- * A callback class that will set it's parent's image.
- */
- private class ImageDownloadedCallback {
- public void onImageDownloaded(Drawable image, String url) {
- boolean imageDownloadSuccess = image != null;
RecordHistogram.recordBooleanHistogram(
- "NewTabPage.Interests.ImageDownloadSuccess", imageDownloadSuccess);
- if (!imageDownloadSuccess) return;
- // If the Interest this View is displaying has changed while downloading, do not update
- // the image.
- if (TextUtils.equals(url, mInterest.getImageUrl())) {
- setImage(image);
- }
- }
- }
-
- /*
- * A holder for an Image that allows listeners to subscribe to when it is set. It is
- * like a listenable future that doesn't calculate the value itself. It can only be
- * accessed on one thread. It can only be set once.
- */
- static class ImageHolder {
- private final ObserverList<ImageDownloadedCallback> mCallbacks = new ObserverList<>();
- private Drawable mImage;
- private String mUrl;
-
- public void set(Drawable image, String url) {
- assert mImage == null;
- mImage = image;
- mUrl = url;
-
- for (ImageDownloadedCallback callbacks : mCallbacks) {
- callbacks.onImageDownloaded(image, mUrl);
- }
-
- mCallbacks.clear();
- }
-
- public void addListener(ImageDownloadedCallback callback) {
- if (mImage == null) {
- mCallbacks.addObserver(callback);
- } else {
- callback.onImageDownloaded(mImage, mUrl);
- }
- }
-
- public Drawable getImageDrawable() {
- return mImage;
+ "NewTabPage.Interests.ImageDownloadSuccess", image != null);
+ mPromise.fulfill(image);
}
}
}

Powered by Google App Engine
This is Rietveld 408576698