From 1221cff561eb2ca321f96c7510e01f9218634bd6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 29 Oct 2015 12:08:15 +0100 Subject: load avatars in message adapter in background task --- .../conversations/services/AvatarService.java | 21 ++++- .../conversations/ui/adapter/MessageAdapter.java | 103 ++++++++++++++++++--- src/main/res/layout/message_received.xml | 4 +- src/main/res/layout/message_sent.xml | 4 +- 4 files changed, 115 insertions(+), 17 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 7412eb93..3cd32d79 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -16,6 +16,7 @@ import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.ListItem; +import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.utils.UIHelper; @@ -179,9 +180,13 @@ public class AvatarService { } public Bitmap get(Account account, int size) { + return get(account, size, false); + } + + public Bitmap get(Account account, int size, boolean cachedOnly) { final String KEY = key(account, size); Bitmap avatar = mXmppConnectionService.getBitmapCache().get(KEY); - if (avatar != null) { + if (avatar != null || cachedOnly) { return avatar; } avatar = mXmppConnectionService.getFileBackend().getAvatar( @@ -193,6 +198,19 @@ public class AvatarService { return avatar; } + public Bitmap get(Message message, int size, boolean cachedOnly) { + if (message.getStatus() == Message.STATUS_RECEIVED) { + Contact contact = message.getContact(); + if (contact != null) { + return get(contact, size, cachedOnly); + } else { + return get(UIHelper.getMessageDisplayName(message), size, cachedOnly); + } + } else { + return get(message.getConversation().getAccount(), size, cachedOnly); + } + } + public void clear(Account account) { synchronized (this.sizes) { for (Integer size : sizes) { @@ -291,5 +309,4 @@ public class AvatarService { Rect dst = new Rect(dstleft, dsttop, dstright, dstbottom); canvas.drawBitmap(bm, null, dst, null); } - } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 42c68eb8..2befd65c 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -4,8 +4,13 @@ import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.graphics.Bitmap; import android.graphics.Typeface; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.AsyncTask; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; @@ -24,7 +29,9 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; +import java.lang.ref.WeakReference; import java.util.List; +import java.util.concurrent.RejectedExecutionException; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; @@ -493,17 +500,8 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.status_message.setText(message.getBody()); } return view; - } else if (type == RECEIVED) { - Contact contact = message.getContact(); - if (contact != null) { - viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(contact, activity.getPixel(48))); - } else if (conversation.getMode() == Conversation.MODE_MULTI) { - viewHolder.contact_picture.setImageBitmap(activity.avatarService().get( - UIHelper.getMessageDisplayName(message), - activity.getPixel(48))); - } - } else if (type == SENT) { - viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48))); + } else { + loadAvatar(message,viewHolder.contact_picture); } viewHolder.contact_picture @@ -674,4 +672,87 @@ public class MessageAdapter extends ArrayAdapter { protected TextView status_message; protected TextView encryption; } + + class BitmapWorkerTask extends AsyncTask { + private final WeakReference imageViewReference; + private Message message = null; + + public BitmapWorkerTask(ImageView imageView) { + imageViewReference = new WeakReference<>(imageView); + } + + @Override + protected Bitmap doInBackground(Message... params) { + return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled()); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null) { + final ImageView imageView = imageViewReference.get(); + if (imageView != null) { + imageView.setImageBitmap(bitmap); + imageView.setBackgroundColor(0x00000000); + } + } + } + } + + public void loadAvatar(Message message, ImageView imageView) { + if (cancelPotentialWork(message, imageView)) { + final Bitmap bm = activity.avatarService().get(message, activity.getPixel(48), true); + if (bm != null) { + imageView.setImageBitmap(bm); + imageView.setBackgroundColor(0x00000000); + } else { + imageView.setBackgroundColor(UIHelper.getColorForName(UIHelper.getMessageDisplayName(message))); + imageView.setImageDrawable(null); + final BitmapWorkerTask task = new BitmapWorkerTask(imageView); + final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); + imageView.setImageDrawable(asyncDrawable); + try { + task.execute(message); + } catch (final RejectedExecutionException ignored) { + } + } + } + } + + public static boolean cancelPotentialWork(Message message, ImageView imageView) { + final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + + if (bitmapWorkerTask != null) { + final Message oldMessage = bitmapWorkerTask.message; + if (oldMessage == null || message != oldMessage) { + bitmapWorkerTask.cancel(true); + } else { + return false; + } + } + return true; + } + + private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { + if (imageView != null) { + final Drawable drawable = imageView.getDrawable(); + if (drawable instanceof AsyncDrawable) { + final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; + return asyncDrawable.getBitmapWorkerTask(); + } + } + return null; + } + + static class AsyncDrawable extends BitmapDrawable { + private final WeakReference bitmapWorkerTaskReference; + + public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); + } + + public BitmapWorkerTask getBitmapWorkerTask() { + return bitmapWorkerTaskReference.get(); + } + } } diff --git a/src/main/res/layout/message_received.xml b/src/main/res/layout/message_received.xml index b6a29e86..a998bf37 100644 --- a/src/main/res/layout/message_received.xml +++ b/src/main/res/layout/message_received.xml @@ -11,8 +11,8 @@