loading avatars in seperate tasks
This commit is contained in:
parent
9ff39a1a1e
commit
0485da8488
|
@ -38,10 +38,10 @@ public class AvatarService {
|
||||||
this.mXmppConnectionService = service;
|
this.mXmppConnectionService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap get(final Contact contact, final int size) {
|
private Bitmap get(final Contact contact, final int size, boolean cachedOnly) {
|
||||||
final String KEY = key(contact, size);
|
final String KEY = key(contact, size);
|
||||||
Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
|
Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
|
||||||
if (avatar != null) {
|
if (avatar != null || cachedOnly) {
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
if (contact.getProfilePhoto() != null) {
|
if (contact.getProfilePhoto() != null) {
|
||||||
|
@ -51,7 +51,7 @@ public class AvatarService {
|
||||||
avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size);
|
avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size);
|
||||||
}
|
}
|
||||||
if (avatar == null) {
|
if (avatar == null) {
|
||||||
avatar = get(contact.getDisplayName(), size);
|
avatar = get(contact.getDisplayName(), size, cachedOnly);
|
||||||
}
|
}
|
||||||
this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
|
this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
|
||||||
return avatar;
|
return avatar;
|
||||||
|
@ -77,25 +77,33 @@ public class AvatarService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap get(ListItem item, int size) {
|
public Bitmap get(ListItem item, int size) {
|
||||||
|
return get(item,size,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap get(ListItem item, int size, boolean cachedOnly) {
|
||||||
if (item instanceof Contact) {
|
if (item instanceof Contact) {
|
||||||
return get((Contact) item, size);
|
return get((Contact) item, size,cachedOnly);
|
||||||
} else if (item instanceof Bookmark) {
|
} else if (item instanceof Bookmark) {
|
||||||
Bookmark bookmark = (Bookmark) item;
|
Bookmark bookmark = (Bookmark) item;
|
||||||
if (bookmark.getConversation() != null) {
|
if (bookmark.getConversation() != null) {
|
||||||
return get(bookmark.getConversation(), size);
|
return get(bookmark.getConversation(), size, cachedOnly);
|
||||||
} else {
|
} else {
|
||||||
return get(bookmark.getDisplayName(), size);
|
return get(bookmark.getDisplayName(), size, cachedOnly);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return get(item.getDisplayName(), size);
|
return get(item.getDisplayName(), size, cachedOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap get(Conversation conversation, int size) {
|
public Bitmap get(Conversation conversation, int size) {
|
||||||
|
return get(conversation,size,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap get(Conversation conversation, int size, boolean cachedOnly) {
|
||||||
if (conversation.getMode() == Conversation.MODE_SINGLE) {
|
if (conversation.getMode() == Conversation.MODE_SINGLE) {
|
||||||
return get(conversation.getContact(), size);
|
return get(conversation.getContact(), size, cachedOnly);
|
||||||
} else {
|
} else {
|
||||||
return get(conversation.getMucOptions(), size);
|
return get(conversation.getMucOptions(), size, cachedOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,10 +115,10 @@ public class AvatarService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap get(MucOptions mucOptions, int size) {
|
private Bitmap get(MucOptions mucOptions, int size, boolean cachedOnly) {
|
||||||
final String KEY = key(mucOptions, size);
|
final String KEY = key(mucOptions, size);
|
||||||
Bitmap bitmap = this.mXmppConnectionService.getBitmapCache().get(KEY);
|
Bitmap bitmap = this.mXmppConnectionService.getBitmapCache().get(KEY);
|
||||||
if (bitmap != null) {
|
if (bitmap != null || cachedOnly) {
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
final List<MucOptions.User> users = new ArrayList<>(mucOptions.getUsers());
|
final List<MucOptions.User> users = new ArrayList<>(mucOptions.getUsers());
|
||||||
|
@ -179,7 +187,7 @@ public class AvatarService {
|
||||||
avatar = mXmppConnectionService.getFileBackend().getAvatar(
|
avatar = mXmppConnectionService.getFileBackend().getAvatar(
|
||||||
account.getAvatar(), size);
|
account.getAvatar(), size);
|
||||||
if (avatar == null) {
|
if (avatar == null) {
|
||||||
avatar = get(account.getJid().toBareJid().toString(), size);
|
avatar = get(account.getJid().toBareJid().toString(), size,false);
|
||||||
}
|
}
|
||||||
mXmppConnectionService.getBitmapCache().put(KEY, avatar);
|
mXmppConnectionService.getBitmapCache().put(KEY, avatar);
|
||||||
return avatar;
|
return avatar;
|
||||||
|
@ -204,10 +212,14 @@ public class AvatarService {
|
||||||
+ String.valueOf(size);
|
+ String.valueOf(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap get(final String name, final int size) {
|
public Bitmap get(String name, int size) {
|
||||||
|
return get(name,size,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap get(final String name, final int size, boolean cachedOnly) {
|
||||||
final String KEY = key(name, size);
|
final String KEY = key(name, size);
|
||||||
Bitmap bitmap = mXmppConnectionService.getBitmapCache().get(KEY);
|
Bitmap bitmap = mXmppConnectionService.getBitmapCache().get(KEY);
|
||||||
if (bitmap != null) {
|
if (bitmap != null || cachedOnly) {
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
package eu.siacs.conversations.ui.adapter;
|
package eu.siacs.conversations.ui.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -11,12 +16,13 @@ import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Downloadable;
|
import eu.siacs.conversations.entities.Downloadable;
|
||||||
import eu.siacs.conversations.entities.DownloadableFile;
|
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.ui.ConversationActivity;
|
import eu.siacs.conversations.ui.ConversationActivity;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
|
@ -98,8 +104,88 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
|
|
||||||
mTimestamp.setText(UIHelper.readableTimeDifference(activity,conversation.getLatestMessage().getTimeSent()));
|
mTimestamp.setText(UIHelper.readableTimeDifference(activity,conversation.getLatestMessage().getTimeSent()));
|
||||||
ImageView profilePicture = (ImageView) view.findViewById(R.id.conversation_image);
|
ImageView profilePicture = (ImageView) view.findViewById(R.id.conversation_image);
|
||||||
profilePicture.setImageBitmap(activity.avatarService().get(conversation, activity.getPixel(56)));
|
loadAvatar(conversation,profilePicture);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BitmapWorkerTask extends AsyncTask<Conversation, Void, Bitmap> {
|
||||||
|
private final WeakReference<ImageView> imageViewReference;
|
||||||
|
private Conversation conversation = null;
|
||||||
|
|
||||||
|
public BitmapWorkerTask(ImageView imageView) {
|
||||||
|
imageViewReference = new WeakReference<>(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Bitmap doInBackground(Conversation... params) {
|
||||||
|
return activity.avatarService().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) {
|
||||||
|
Bitmap bm = activity.avatarService().get(conversation,activity.getPixel(56),true);
|
||||||
|
if (bm != null) {
|
||||||
|
imageView.setImageBitmap(bm);
|
||||||
|
imageView.setBackgroundColor(0x00000000);
|
||||||
|
} else if (cancelPotentialWork(conversation, imageView)) {
|
||||||
|
imageView.setBackgroundColor(0xff333333);
|
||||||
|
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<BitmapWorkerTask> bitmapWorkerTaskReference;
|
||||||
|
|
||||||
|
public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
|
||||||
|
super(res, bitmap);
|
||||||
|
bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitmapWorkerTask getBitmapWorkerTask() {
|
||||||
|
return bitmapWorkerTaskReference.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,23 @@
|
||||||
package eu.siacs.conversations.ui.adapter;
|
package eu.siacs.conversations.ui.adapter;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.ListItem;
|
import eu.siacs.conversations.entities.ListItem;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -77,8 +85,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
|
||||||
tvJid.setText("");
|
tvJid.setText("");
|
||||||
}
|
}
|
||||||
tvName.setText(item.getDisplayName());
|
tvName.setText(item.getDisplayName());
|
||||||
picture.setImageBitmap(activity.avatarService().get(item,
|
loadAvatar(item,picture);
|
||||||
activity.getPixel(48)));
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,4 +97,84 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
|
||||||
public void onTagClicked(String tag);
|
public void onTagClicked(String tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BitmapWorkerTask extends AsyncTask<ListItem, Void, Bitmap> {
|
||||||
|
private final WeakReference<ImageView> imageViewReference;
|
||||||
|
private ListItem item = null;
|
||||||
|
|
||||||
|
public BitmapWorkerTask(ImageView imageView) {
|
||||||
|
imageViewReference = new WeakReference<>(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Bitmap doInBackground(ListItem... params) {
|
||||||
|
return activity.avatarService().get(params[0], activity.getPixel(48));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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(ListItem item, ImageView imageView) {
|
||||||
|
Bitmap bm = activity.avatarService().get(item,activity.getPixel(56),true);
|
||||||
|
if (bm != null) {
|
||||||
|
imageView.setImageBitmap(bm);
|
||||||
|
imageView.setBackgroundColor(0x00000000);
|
||||||
|
} else if (cancelPotentialWork(item, imageView)) {
|
||||||
|
imageView.setBackgroundColor(0xff333333);
|
||||||
|
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
|
||||||
|
final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
|
||||||
|
imageView.setImageDrawable(asyncDrawable);
|
||||||
|
try {
|
||||||
|
task.execute(item);
|
||||||
|
} catch (final RejectedExecutionException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean cancelPotentialWork(ListItem item, ImageView imageView) {
|
||||||
|
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||||
|
|
||||||
|
if (bitmapWorkerTask != null) {
|
||||||
|
final ListItem oldItem = bitmapWorkerTask.item;
|
||||||
|
if (oldItem == null || item != oldItem) {
|
||||||
|
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<BitmapWorkerTask> bitmapWorkerTaskReference;
|
||||||
|
|
||||||
|
public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
|
||||||
|
super(res, bitmap);
|
||||||
|
bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitmapWorkerTask getBitmapWorkerTask() {
|
||||||
|
return bitmapWorkerTaskReference.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue