Commit dc5e5342 authored by Grigory Fedorov's avatar Grigory Fedorov

AvatarManager: fix for #418 crash with conference notifications (drawable to bitmap conversion)

parent 2cc0fb51
...@@ -70,51 +70,40 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac ...@@ -70,51 +70,40 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
private static final String EMPTY_HASH = ""; private static final String EMPTY_HASH = "";
private static final Bitmap EMPTY_BITMAP = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); private static final Bitmap EMPTY_BITMAP = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
private final static AvatarManager instance;
private final Application application; static {
instance = new AvatarManager();
Application.getInstance().addManager(instance);
}
private final Application application;
/** /**
* Map with hashes for specified users. * Map with hashes for specified users.
* <p/> * <p/>
* {@link #EMPTY_HASH} is used to store <code>null</code> values. * {@link #EMPTY_HASH} is used to store <code>null</code> values.
*/ */
private final Map<String, String> hashes; private final Map<String, String> hashes;
/** /**
* Map with bitmaps for specified hashes. * Map with bitmaps for specified hashes.
* <p/> * <p/>
* {@link #EMPTY_BITMAP} is used to store <code>null</code> values. * {@link #EMPTY_BITMAP} is used to store <code>null</code> values.
*/ */
private final Map<String, Bitmap> bitmaps; private final Map<String, Bitmap> bitmaps;
/** /**
* Map with drawable used in contact list only for specified uses. * Map with drawable used in contact list only for specified uses.
*/ */
private final Map<String, Drawable> contactListDrawables; private final Map<String, Drawable> contactListDrawables;
/** /**
* Users' default avatar set. * Users' default avatar set.
*/ */
private final BaseAvatarSet userAvatarSet; private final BaseAvatarSet userAvatarSet;
/** /**
* Rooms' default avatar set. * Rooms' default avatar set.
*/ */
private final BaseAvatarSet roomAvatarSet; private final BaseAvatarSet roomAvatarSet;
private final static AvatarManager instance;
static {
instance = new AvatarManager();
Application.getInstance().addManager(instance);
}
private final int[] accountColors; private final int[] accountColors;
public static AvatarManager getInstance() {
return instance;
}
private AvatarManager() { private AvatarManager() {
this.application = Application.getInstance(); this.application = Application.getInstance();
userAvatarSet = new BaseAvatarSet(application, R.array.default_avatars_icons, R.array.default_avatars_colors); userAvatarSet = new BaseAvatarSet(application, R.array.default_avatars_icons, R.array.default_avatars_colors);
...@@ -127,6 +116,61 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac ...@@ -127,6 +116,61 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
contactListDrawables = new HashMap<>(); contactListDrawables = new HashMap<>();
} }
public static AvatarManager getInstance() {
return instance;
}
/**
* Make {@link Bitmap} from array of bytes.
*
* @param value
* @return Bitmap. <code>null</code> can be returned if value is invalid or
* is <code>null</code>.
*/
private static Bitmap makeBitmap(byte[] value) {
if (value == null) {
return null;
}
// Load only size values
BitmapFactory.Options sizeOptions = new BitmapFactory.Options();
sizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(value, 0, value.length, sizeOptions);
// Calculate factor to down scale image
int scale = 1;
int width_tmp = sizeOptions.outWidth;
int height_tmp = sizeOptions.outHeight;
while (width_tmp / 2 >= MAX_SIZE && height_tmp / 2 >= MAX_SIZE) {
scale *= 2;
width_tmp /= 2;
height_tmp /= 2;
}
// Load image
BitmapFactory.Options resultOptions = new BitmapFactory.Options();
resultOptions.inSampleSize = scale;
return BitmapFactory.decodeByteArray(value, 0, value.length, resultOptions);
}
public static Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
int width = drawable.getIntrinsicWidth();
width = width > 0 ? width : 1;
int height = drawable.getIntrinsicHeight();
height = height > 0 ? height : 1;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
@Override @Override
public void onLoad() { public void onLoad() {
final Map<String, String> hashes = new HashMap<>(); final Map<String, String> hashes = new HashMap<>();
...@@ -177,39 +221,6 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac ...@@ -177,39 +221,6 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
}); });
} }
/**
* Make {@link Bitmap} from array of bytes.
*
* @param value
* @return Bitmap. <code>null</code> can be returned if value is invalid or
* is <code>null</code>.
*/
private static Bitmap makeBitmap(byte[] value) {
if (value == null) {
return null;
}
// Load only size values
BitmapFactory.Options sizeOptions = new BitmapFactory.Options();
sizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(value, 0, value.length, sizeOptions);
// Calculate factor to down scale image
int scale = 1;
int width_tmp = sizeOptions.outWidth;
int height_tmp = sizeOptions.outHeight;
while (width_tmp / 2 >= MAX_SIZE && height_tmp / 2 >= MAX_SIZE) {
scale *= 2;
width_tmp /= 2;
height_tmp /= 2;
}
// Load image
BitmapFactory.Options resultOptions = new BitmapFactory.Options();
resultOptions.inSampleSize = scale;
return BitmapFactory.decodeByteArray(value, 0, value.length, resultOptions);
}
/** /**
* Get avatar's value for user. * Get avatar's value for user.
* *
...@@ -317,14 +328,7 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac ...@@ -317,14 +328,7 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
if (value != null) { if (value != null) {
return value; return value;
} else { } else {
Drawable drawable = getDefaultAvatarDrawable(userAvatarSet.getResourceId(user)); return drawableToBitmap(getDefaultAvatarDrawable(userAvatarSet.getResourceId(user)));
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} }
} }
...@@ -360,7 +364,7 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac ...@@ -360,7 +364,7 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener, OnPac
* @return * @return
*/ */
public Bitmap getRoomBitmap(String user) { public Bitmap getRoomBitmap(String user) {
return ((BitmapDrawable) getRoomAvatar(user)).getBitmap(); return drawableToBitmap(getRoomAvatar(user));
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment