AvatarWorkerTask.java

  1package eu.siacs.conversations.ui.util;
  2
  3import android.content.Context;
  4import android.content.res.Resources;
  5import android.graphics.Bitmap;
  6import android.graphics.drawable.BitmapDrawable;
  7import android.graphics.drawable.Drawable;
  8import android.os.AsyncTask;
  9import android.support.annotation.DimenRes;
 10import android.widget.ImageView;
 11
 12import java.lang.ref.WeakReference;
 13import java.util.concurrent.RejectedExecutionException;
 14
 15import eu.siacs.conversations.R;
 16import eu.siacs.conversations.entities.Account;
 17import eu.siacs.conversations.services.AvatarService;
 18import eu.siacs.conversations.ui.XmppActivity;
 19
 20public class AvatarWorkerTask extends AsyncTask<AvatarService.Avatarable, Void, Bitmap> {
 21    private final WeakReference<ImageView> imageViewReference;
 22    private AvatarService.Avatarable avatarable = null;
 23    private @DimenRes int size;
 24
 25    public AvatarWorkerTask(ImageView imageView, @DimenRes int size) {
 26        imageViewReference = new WeakReference<>(imageView);
 27        this.size = size;
 28    }
 29
 30    @Override
 31    protected Bitmap doInBackground(AvatarService.Avatarable... params) {
 32        this.avatarable = params[0];
 33        final XmppActivity activity = XmppActivity.find(imageViewReference);
 34        if (activity == null) {
 35            return null;
 36        }
 37        return activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), isCancelled());
 38    }
 39
 40    @Override
 41    protected void onPostExecute(Bitmap bitmap) {
 42        if (bitmap != null && !isCancelled()) {
 43            final ImageView imageView = imageViewReference.get();
 44            if (imageView != null) {
 45                imageView.setImageBitmap(bitmap);
 46                imageView.setBackgroundColor(0x00000000);
 47            }
 48        }
 49    }
 50
 51    public static boolean cancelPotentialWork(AvatarService.Avatarable avatarable, ImageView imageView) {
 52        final AvatarWorkerTask workerTask = getBitmapWorkerTask(imageView);
 53
 54        if (workerTask != null) {
 55            final AvatarService.Avatarable old= workerTask.avatarable;
 56            if (old == null || avatarable != old) {
 57                workerTask.cancel(true);
 58            } else {
 59                return false;
 60            }
 61        }
 62        return true;
 63    }
 64
 65    public static AvatarWorkerTask getBitmapWorkerTask(ImageView imageView) {
 66        if (imageView != null) {
 67            final Drawable drawable = imageView.getDrawable();
 68            if (drawable instanceof AsyncDrawable) {
 69                final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
 70                return asyncDrawable.getAvatarWorkerTask();
 71            }
 72        }
 73        return null;
 74    }
 75
 76    public static void loadAvatar(final AvatarService.Avatarable avatarable, final ImageView imageView, final @DimenRes int size) {
 77        if (cancelPotentialWork(avatarable, imageView)) {
 78            final XmppActivity activity = XmppActivity.find(imageView);
 79            if (activity == null) {
 80                return;
 81            }
 82            final Bitmap bm = activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), true);
 83            setContentDescription(avatarable, imageView);
 84            if (bm != null) {
 85                cancelPotentialWork(avatarable, imageView);
 86                imageView.setImageBitmap(bm);
 87                imageView.setBackgroundColor(0x00000000);
 88            } else {
 89                imageView.setBackgroundColor(avatarable.getAvatarBackgroundColor());
 90                imageView.setImageDrawable(null);
 91                final AvatarWorkerTask task = new AvatarWorkerTask(imageView, size);
 92                final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
 93                imageView.setImageDrawable(asyncDrawable);
 94                try {
 95                    task.execute(avatarable);
 96                } catch (final RejectedExecutionException ignored) {
 97                }
 98            }
 99        }
100    }
101
102    private static void setContentDescription(final AvatarService.Avatarable avatarable, final ImageView imageView) {
103        final Context context = imageView.getContext();
104        if (avatarable instanceof Account) {
105            imageView.setContentDescription(context.getString(R.string.your_avatar));
106        } else {
107            imageView.setContentDescription(context.getString(R.string.avatar_for_x, avatarable.getAvatarName()));
108        }
109    }
110
111    static class AsyncDrawable extends BitmapDrawable {
112        private final WeakReference<AvatarWorkerTask> avatarWorkerTaskReference;
113
114        AsyncDrawable(Resources res, Bitmap bitmap, AvatarWorkerTask workerTask) {
115            super(res, bitmap);
116            avatarWorkerTaskReference = new WeakReference<>(workerTask);
117        }
118
119        AvatarWorkerTask getAvatarWorkerTask() {
120            return avatarWorkerTaskReference.get();
121        }
122    }
123}