From 6f588444a953a54543661f7603d45a9093b7196a Mon Sep 17 00:00:00 2001 From: steckbrief Date: Sat, 5 Aug 2017 22:25:23 +0200 Subject: Implements FS#249: Remove code duplication for avatar creation --- .../conversationsplus/dto/LoadAvatarFor.java | 6 ++ .../conversationsplus/entities/Conversation.java | 3 +- .../conversationsplus/entities/Message.java | 3 +- .../conversationsplus/services/AvatarService.java | 58 +++++++++++++ .../conversationsplus/ui/AsyncDrawable.java | 23 ++++++ .../ui/adapter/ConversationAdapter.java | 93 +-------------------- .../ui/adapter/MessageAdapter.java | 96 +--------------------- .../ui/tasks/AvatarBitmapTask.java | 47 +++++++++++ 8 files changed, 140 insertions(+), 189 deletions(-) create mode 100644 src/main/java/de/thedevstack/conversationsplus/dto/LoadAvatarFor.java create mode 100644 src/main/java/de/thedevstack/conversationsplus/ui/AsyncDrawable.java create mode 100644 src/main/java/de/thedevstack/conversationsplus/ui/tasks/AvatarBitmapTask.java diff --git a/src/main/java/de/thedevstack/conversationsplus/dto/LoadAvatarFor.java b/src/main/java/de/thedevstack/conversationsplus/dto/LoadAvatarFor.java new file mode 100644 index 00000000..93a1ba92 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/dto/LoadAvatarFor.java @@ -0,0 +1,6 @@ +package de.thedevstack.conversationsplus.dto; + +/** + */ +public interface LoadAvatarFor { +} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java index c0ae56fd..2edd1135 100644 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java +++ b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java @@ -21,6 +21,7 @@ import java.util.Comparator; import java.util.Iterator; import java.util.List; +import de.thedevstack.conversationsplus.dto.LoadAvatarFor; import de.thedevstack.conversationsplus.utils.MessageUtil; import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.crypto.axolotl.AxolotlService; @@ -28,7 +29,7 @@ import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState; import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; import de.thedevstack.conversationsplus.xmpp.jid.Jid; -public class Conversation extends AbstractEntity implements Blockable { +public class Conversation extends AbstractEntity implements Blockable, LoadAvatarFor { public static final String TABLENAME = "conversations"; public static final int STATUS_AVAILABLE = 0; diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java index 4d7697f2..b8ebfe2b 100644 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java +++ b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java @@ -7,6 +7,7 @@ import java.net.MalformedURLException; import java.net.URL; import de.thedevstack.conversationsplus.crypto.axolotl.XmppAxolotlSession; +import de.thedevstack.conversationsplus.dto.LoadAvatarFor; import de.thedevstack.conversationsplus.enums.FileStatus; import de.thedevstack.conversationsplus.utils.FileUtils; import de.thedevstack.conversationsplus.utils.MessageUtil; @@ -14,7 +15,7 @@ import de.thedevstack.conversationsplus.utils.MimeUtils; import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; import de.thedevstack.conversationsplus.xmpp.jid.Jid; -public class Message extends AbstractEntity { +public class Message extends AbstractEntity implements LoadAvatarFor { public static final String TABLENAME = "messages"; diff --git a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java index ed9c259f..0e10b883 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java @@ -1,19 +1,27 @@ package de.thedevstack.conversationsplus.services; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; +import android.graphics.drawable.Drawable; import android.net.Uri; +import android.widget.ImageView; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.concurrent.RejectedExecutionException; import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.dto.LoadAvatarFor; +import de.thedevstack.conversationsplus.ui.AsyncDrawable; +import de.thedevstack.conversationsplus.ui.adapter.ConversationAdapter; +import de.thedevstack.conversationsplus.ui.tasks.AvatarBitmapTask; import de.thedevstack.conversationsplus.utils.AvatarUtil; import de.thedevstack.conversationsplus.utils.ImageUtil; import de.thedevstack.conversationsplus.utils.UiUpdateHelper; @@ -176,6 +184,56 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { } } + public void loadAvatar(LoadAvatarFor loadAvatarFor, ImageView imageView) { + if (cancelPotentialWork(imageView)) { + Resources resources = ConversationsPlusApplication.getAppContext().getResources(); + int avatarSize = resources.getDimensionPixelSize(R.dimen.avatar_size); + final Bitmap bm; + if (loadAvatarFor instanceof Conversation) { + bm = AvatarService.getInstance().get((Conversation) loadAvatarFor, avatarSize, true); + } else if (loadAvatarFor instanceof Message) { + bm = AvatarService.getInstance().get((Message) loadAvatarFor, avatarSize, true); + } else { + bm = null; + } + if (bm != null) { + imageView.setImageBitmap(bm); + imageView.setBackgroundColor(0x00000000); + } else { + int color = 0x00000000; + if (loadAvatarFor instanceof Conversation) { + color = UIHelper.getColorForName(((Conversation) loadAvatarFor).getName()); + } else if (loadAvatarFor instanceof Message) { + color = UIHelper.getColorForName(UIHelper.getMessageDisplayName((Message) loadAvatarFor)); + } + imageView.setBackgroundColor(color); + imageView.setImageDrawable(null); + final AvatarBitmapTask task = new AvatarBitmapTask<>(imageView, avatarSize); + final AsyncDrawable asyncDrawable = new AsyncDrawable(resources, null, task); + imageView.setImageDrawable(asyncDrawable); + try { + task.execute(loadAvatarFor); + } catch (final RejectedExecutionException ignored) { + } + } + } + } + + public static boolean cancelPotentialWork(ImageView imageView) { + return null == getBitmapWorkerTask(imageView); + } + + private static AvatarBitmapTask 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; + } + private Bitmap get(MucOptions mucOptions, int size, boolean cachedOnly) { final String KEY = key(mucOptions, size); Bitmap bitmap = ImageUtil.getBitmapFromCache(KEY); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/AsyncDrawable.java b/src/main/java/de/thedevstack/conversationsplus/ui/AsyncDrawable.java new file mode 100644 index 00000000..52a9c74f --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/AsyncDrawable.java @@ -0,0 +1,23 @@ +package de.thedevstack.conversationsplus.ui; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; + +import java.lang.ref.WeakReference; + +import de.thedevstack.conversationsplus.dto.LoadAvatarFor; +import de.thedevstack.conversationsplus.ui.tasks.AvatarBitmapTask; + +public class AsyncDrawable extends BitmapDrawable { + private final WeakReference> bitmapWorkerTaskReference; + + public AsyncDrawable(Resources res, Bitmap bitmap, AvatarBitmapTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); + } + + public AvatarBitmapTask getBitmapWorkerTask() { + return bitmapWorkerTaskReference.get(); + } + } \ No newline at end of file diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java index 9e550988..8388d449 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java @@ -1,13 +1,7 @@ package de.thedevstack.conversationsplus.ui.adapter; import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Color; import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; @@ -16,9 +10,7 @@ import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; -import java.lang.ref.WeakReference; import java.util.List; -import java.util.concurrent.RejectedExecutionException; import de.thedevstack.conversationsplus.ConversationsPlusColors; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; @@ -155,91 +147,8 @@ public class ConversationAdapter extends ArrayAdapter { if (conversation.getMode() == Conversation.MODE_SINGLE) { profilePicture.setOnLongClickListener(new ShowResourcesListDialogListener(activity, conversation.getContact())); } - loadAvatar(conversation, profilePicture); + AvatarService.getInstance().loadAvatar(conversation, profilePicture); return view; } - - class BitmapWorkerTask extends AsyncTask { - private final WeakReference imageViewReference; - private Conversation conversation = null; - - public BitmapWorkerTask(ImageView imageView) { - imageViewReference = new WeakReference<>(imageView); - } - - @Override - protected Bitmap doInBackground(Conversation... params) { - return AvatarService.getInstance().get(params[0], activity.getPixel(56)); - } - - @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(Conversation conversation, ImageView imageView) { - if (cancelPotentialWork(conversation, imageView)) { - final Bitmap bm = AvatarService.getInstance().get(conversation, activity.getPixel(56), true); - if (bm != null) { - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(0x00000000); - } else { - imageView.setBackgroundColor(UIHelper.getColorForName(conversation.getName())); - imageView.setImageDrawable(null); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView); - final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(conversation); - } catch (final RejectedExecutionException ignored) { - } - } - } - } - - public static boolean cancelPotentialWork(Conversation conversation, ImageView imageView) { - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final Conversation oldConversation = bitmapWorkerTask.conversation; - if (oldConversation == null || conversation != oldConversation) { - 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(); - } - } } \ No newline at end of file diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java index a4711aa0..3cf50925 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java @@ -4,13 +4,8 @@ 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; @@ -32,10 +27,7 @@ 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 java.util.regex.Matcher; import java.util.regex.Pattern; @@ -570,33 +562,11 @@ public class MessageAdapter extends ArrayAdapter { } } - - private void loadAvatar(Message message, ImageView imageView) { - if (cancelPotentialWork(message, imageView)) { - int avatarPixel = imageView.getResources().getDimensionPixelOffset(R.dimen.msg_avatar_size); - final Bitmap bm = AvatarService.getInstance().get(message, avatarPixel, 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) { - } - } - } - } - private void displayAvatar(final Message message, int type, ViewHolder viewHolder) { if (type == ME_COMMAND || (type == RECEIVED)) { // && message.getConversation().getMode() == Conversation.MODE_MULTI ImageView imageView = viewHolder.contact_picture; if (null != imageView) { - this.loadAvatar(message, imageView); + AvatarService.getInstance().loadAvatar(message, imageView); imageView.setOnClickListener(new OnClickListener() { @@ -842,68 +812,4 @@ public class MessageAdapter extends ArrayAdapter { public TextView remoteFileStatus; protected boolean darkBackground; } - - 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) { - int avatarPixel = activity.getResources().getDimensionPixelOffset(R.dimen.msg_avatar_size); - return AvatarService.getInstance().get(params[0], avatarPixel, 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 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(); - } - } } \ No newline at end of file diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/tasks/AvatarBitmapTask.java b/src/main/java/de/thedevstack/conversationsplus/ui/tasks/AvatarBitmapTask.java new file mode 100644 index 00000000..ec89b001 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/tasks/AvatarBitmapTask.java @@ -0,0 +1,47 @@ +package de.thedevstack.conversationsplus.ui.tasks; + +import android.graphics.Bitmap; +import android.os.AsyncTask; +import android.widget.ImageView; + +import java.lang.ref.WeakReference; + +import de.thedevstack.conversationsplus.dto.LoadAvatarFor; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.services.AvatarService; + +/** + * + */ +public class AvatarBitmapTask extends AsyncTask { + private final WeakReference imageViewReference; + private int avatarSize; + + public AvatarBitmapTask(ImageView imageView, int size) { + imageViewReference = new WeakReference<>(imageView); + this.avatarSize = size; + } + + @Override + protected Bitmap doInBackground(T... params) { + if (params[0] instanceof Conversation) { + return AvatarService.getInstance().get((Conversation)params[0], this.avatarSize); + } else if (params[0] instanceof Message) { + return AvatarService.getInstance().get((Message) params[0], this.avatarSize, isCancelled()); // Wirklich die richtige Nutzung von isCancelled()??? + } else { + return null; + } + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null) { + final ImageView imageView = imageViewReference.get(); + if (imageView != null) { + imageView.setImageBitmap(bitmap); + imageView.setBackgroundColor(0x00000000); + } + } + } +} -- cgit v1.2.3