loading avatars in seperate tasks

This commit is contained in:
iNPUTmice 2015-02-15 18:48:05 +01:00
parent 9ff39a1a1e
commit 0485da8488
3 changed files with 203 additions and 18 deletions

View file

@ -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);

View file

@ -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();
}
}
} }

View file

@ -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();
}
}
} }