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;
}
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);
Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
if (avatar != null) {
if (avatar != null || cachedOnly) {
return avatar;
}
if (contact.getProfilePhoto() != null) {
@ -51,7 +51,7 @@ public class AvatarService {
avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size);
}
if (avatar == null) {
avatar = get(contact.getDisplayName(), size);
avatar = get(contact.getDisplayName(), size, cachedOnly);
}
this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
return avatar;
@ -77,25 +77,33 @@ public class AvatarService {
}
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) {
return get((Contact) item, size);
return get((Contact) item, size,cachedOnly);
} else if (item instanceof Bookmark) {
Bookmark bookmark = (Bookmark) item;
if (bookmark.getConversation() != null) {
return get(bookmark.getConversation(), size);
return get(bookmark.getConversation(), size, cachedOnly);
} else {
return get(bookmark.getDisplayName(), size);
return get(bookmark.getDisplayName(), size, cachedOnly);
}
} else {
return get(item.getDisplayName(), size);
return get(item.getDisplayName(), size, cachedOnly);
}
}
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) {
return get(conversation.getContact(), size);
return get(conversation.getContact(), size, cachedOnly);
} 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);
Bitmap bitmap = this.mXmppConnectionService.getBitmapCache().get(KEY);
if (bitmap != null) {
if (bitmap != null || cachedOnly) {
return bitmap;
}
final List<MucOptions.User> users = new ArrayList<>(mucOptions.getUsers());
@ -179,7 +187,7 @@ public class AvatarService {
avatar = mXmppConnectionService.getFileBackend().getAvatar(
account.getAvatar(), size);
if (avatar == null) {
avatar = get(account.getJid().toBareJid().toString(), size);
avatar = get(account.getJid().toBareJid().toString(), size,false);
}
mXmppConnectionService.getBitmapCache().put(KEY, avatar);
return avatar;
@ -204,10 +212,14 @@ public class AvatarService {
+ 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);
Bitmap bitmap = mXmppConnectionService.getBitmapCache().get(KEY);
if (bitmap != null) {
if (bitmap != null || cachedOnly) {
return bitmap;
}
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);

View file

@ -1,8 +1,13 @@
package eu.siacs.conversations.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;
@ -11,12 +16,13 @@ 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 eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Downloadable;
import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.ConversationActivity;
import eu.siacs.conversations.ui.XmppActivity;
@ -98,8 +104,88 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
mTimestamp.setText(UIHelper.readableTimeDifference(activity,conversation.getLatestMessage().getTimeSent()));
ImageView profilePicture = (ImageView) view.findViewById(R.id.conversation_image);
profilePicture.setImageBitmap(activity.avatarService().get(conversation, activity.getPixel(56)));
loadAvatar(conversation,profilePicture);
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;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.xmpp.jid.Jid;
import android.content.Context;
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.util.Log;
import android.view.LayoutInflater;
@ -77,8 +85,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
tvJid.setText("");
}
tvName.setText(item.getDisplayName());
picture.setImageBitmap(activity.avatarService().get(item,
activity.getPixel(48)));
loadAvatar(item,picture);
return view;
}
@ -90,4 +97,84 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
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();
}
}
}