com.bumptech.glide.util.Util Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of glide Show documentation
Show all versions of glide Show documentation
A fast and efficient image loading library for Android focused on smooth scrolling.
package com.bumptech.glide.util;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Looper;
import com.bumptech.glide.request.target.Target;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
/**
* A collection of assorted utility classes.
*/
public final class Util {
private static final int HASH_MULTIPLIER = 31;
private static final int HASH_ACCUMULATOR = 17;
private static final char[] HEX_CHAR_ARRAY = "0123456789abcdef".toCharArray();
// 32 bytes from sha-256 -> 64 hex chars.
private static final char[] SHA_256_CHARS = new char[64];
private Util() {
// Utility class.
}
/**
* Returns the hex string of the given byte array representing a SHA256 hash.
*/
public static String sha256BytesToHex(byte[] bytes) {
synchronized (SHA_256_CHARS) {
return bytesToHex(bytes, SHA_256_CHARS);
}
}
// Taken from:
// http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
// /9655275#9655275
@SuppressWarnings("PMD.UseVarargs")
private static String bytesToHex(byte[] bytes, char[] hexChars) {
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_CHAR_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_CHAR_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
/**
* Returns the allocated byte size of the given bitmap.
*
* @see #getBitmapByteSize(android.graphics.Bitmap)
* @deprecated Use {@link #getBitmapByteSize(android.graphics.Bitmap)} instead. Scheduled to be
* removed in Glide 4.0.
*/
@Deprecated
public static int getSize(Bitmap bitmap) {
return getBitmapByteSize(bitmap);
}
/**
* Returns the in memory size of the given {@link Bitmap} in bytes.
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public static int getBitmapByteSize(Bitmap bitmap) {
// The return value of getAllocationByteCount silently changes for recycled bitmaps from the
// internal buffer size to row bytes * height. To avoid random inconsistencies in caches, we
// instead assert here.
if (bitmap.isRecycled()) {
throw new IllegalStateException("Cannot obtain size for recycled Bitmap: " + bitmap
+ "[" + bitmap.getWidth() + "x" + bitmap.getHeight() + "] " + bitmap.getConfig());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Workaround for KitKat initial release NPE in Bitmap, fixed in MR1. See issue #148.
try {
return bitmap.getAllocationByteCount();
} catch (NullPointerException e) {
// Do nothing.
}
}
return bitmap.getHeight() * bitmap.getRowBytes();
}
/**
* Returns the in memory size of {@link android.graphics.Bitmap} with the given width, height, and
* {@link android.graphics.Bitmap.Config}.
*/
public static int getBitmapByteSize(int width, int height, Bitmap.Config config) {
return width * height * getBytesPerPixel(config);
}
private static int getBytesPerPixel(Bitmap.Config config) {
// A bitmap by decoding a GIF has null "config" in certain environments.
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}
int bytesPerPixel;
switch (config) {
case ALPHA_8:
bytesPerPixel = 1;
break;
case RGB_565:
case ARGB_4444:
bytesPerPixel = 2;
break;
case ARGB_8888:
default:
bytesPerPixel = 4;
break;
}
return bytesPerPixel;
}
/**
* Returns true if width and height are both > 0 and/or equal to {@link Target#SIZE_ORIGINAL}.
*/
public static boolean isValidDimensions(int width, int height) {
return isValidDimension(width) && isValidDimension(height);
}
private static boolean isValidDimension(int dimen) {
return dimen > 0 || dimen == Target.SIZE_ORIGINAL;
}
/**
* Throws an {@link java.lang.IllegalArgumentException} if called on a thread other than the main
* thread.
*/
public static void assertMainThread() {
if (!isOnMainThread()) {
throw new IllegalArgumentException("You must call this method on the main thread");
}
}
/**
* Throws an {@link java.lang.IllegalArgumentException} if called on the main thread.
*/
public static void assertBackgroundThread() {
if (!isOnBackgroundThread()) {
throw new IllegalArgumentException("You must call this method on a background thread");
}
}
/**
* Returns {@code true} if called on the main thread, {@code false} otherwise.
*/
public static boolean isOnMainThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
/**
* Returns {@code true} if called on a background thread, {@code false} otherwise.
*/
public static boolean isOnBackgroundThread() {
return !isOnMainThread();
}
/**
* Creates a {@link java.util.Queue} of the given size using Glide's preferred implementation.
*/
public static Queue createQueue(int size) {
return new ArrayDeque<>(size);
}
/**
* Returns a copy of the given list that is safe to iterate over and perform actions that may
* modify the original list.
*
* See #303 and #375.
*/
public static List getSnapshot(Collection other) {
// toArray creates a new ArrayList internally and this way we can guarantee entries will not
// be null. See #322.
List result = new ArrayList(other.size());
for (T item : other) {
result.add(item);
}
return result;
}
/**
* Null-safe equivalent of {@code a.equals(b)}.
*
* @see java.util.Objects#equals
*/
public static boolean bothNullOrEqual(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
public static int hashCode(int value) {
return hashCode(value, HASH_ACCUMULATOR);
}
public static int hashCode(int value, int accumulator) {
return accumulator * HASH_MULTIPLIER + value;
}
public static int hashCode(float value) {
return hashCode(value, HASH_ACCUMULATOR);
}
public static int hashCode(float value, int accumulator) {
return hashCode(Float.floatToIntBits(value), accumulator);
}
public static int hashCode(Object object, int accumulator) {
return hashCode(object == null ? 0 : object.hashCode(), accumulator);
}
public static int hashCode(boolean value, int accumulator) {
return hashCode(value ? 1 : 0, accumulator);
}
public static int hashCode(boolean value) {
return hashCode(value, HASH_ACCUMULATOR);
}
}