提交 7663c214 编写于 作者: S Sam Judd

Add support for passing through Bitmaps and Drawables.

上级 f7a939ec
...@@ -54,9 +54,11 @@ import com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser; ...@@ -54,9 +54,11 @@ import com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser;
import com.bumptech.glide.load.resource.bitmap.Downsampler; import com.bumptech.glide.load.resource.bitmap.Downsampler;
import com.bumptech.glide.load.resource.bitmap.ResourceBitmapDecoder; import com.bumptech.glide.load.resource.bitmap.ResourceBitmapDecoder;
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder; import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;
import com.bumptech.glide.load.resource.bitmap.UnitBitmapDecoder;
import com.bumptech.glide.load.resource.bitmap.VideoBitmapDecoder; import com.bumptech.glide.load.resource.bitmap.VideoBitmapDecoder;
import com.bumptech.glide.load.resource.bytes.ByteBufferRewinder; import com.bumptech.glide.load.resource.bytes.ByteBufferRewinder;
import com.bumptech.glide.load.resource.drawable.ResourceDrawableDecoder; import com.bumptech.glide.load.resource.drawable.ResourceDrawableDecoder;
import com.bumptech.glide.load.resource.drawable.UnitDrawableDecoder;
import com.bumptech.glide.load.resource.file.FileDecoder; import com.bumptech.glide.load.resource.file.FileDecoder;
import com.bumptech.glide.load.resource.gif.ByteBufferGifDecoder; import com.bumptech.glide.load.resource.gif.ByteBufferGifDecoder;
import com.bumptech.glide.load.resource.gif.GifDrawable; import com.bumptech.glide.load.resource.gif.GifDrawable;
...@@ -321,6 +323,9 @@ public class Glide implements ComponentCallbacks2 { ...@@ -321,6 +323,9 @@ public class Glide implements ComponentCallbacks2 {
.append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder) .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder)
.append( .append(
Registry.BUCKET_BITMAP, ParcelFileDescriptor.class, Bitmap.class, videoBitmapDecoder) Registry.BUCKET_BITMAP, ParcelFileDescriptor.class, Bitmap.class, videoBitmapDecoder)
.append(
Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder(bitmapPool))
.append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
.append(Bitmap.class, bitmapEncoder) .append(Bitmap.class, bitmapEncoder)
/* BitmapDrawables */ /* BitmapDrawables */
.append( .append(
...@@ -406,6 +411,8 @@ public class Glide implements ComponentCallbacks2 { ...@@ -406,6 +411,8 @@ public class Glide implements ComponentCallbacks2 {
.append(byte[].class, ByteBuffer.class, new ByteArrayLoader.ByteBufferFactory()) .append(byte[].class, ByteBuffer.class, new ByteArrayLoader.ByteBufferFactory())
.append(byte[].class, InputStream.class, new ByteArrayLoader.StreamFactory()) .append(byte[].class, InputStream.class, new ByteArrayLoader.StreamFactory())
.append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance()) .append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance())
.append(Drawable.class, Drawable.class, UnitModelLoader.Factory.<Drawable>getInstance())
.append(Drawable.class, Drawable.class, new UnitDrawableDecoder(bitmapPool))
/* Transcoders */ /* Transcoders */
.register( .register(
Bitmap.class, Bitmap.class,
......
package com.bumptech.glide; package com.bumptech.glide;
import static com.bumptech.glide.request.RequestOptions.diskCacheStrategyOf;
import static com.bumptech.glide.request.RequestOptions.signatureOf; import static com.bumptech.glide.request.RequestOptions.signatureOf;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.CheckResult; import android.support.annotation.CheckResult;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
...@@ -317,7 +320,58 @@ public class RequestBuilder<TranscodeType> implements Cloneable { ...@@ -317,7 +320,58 @@ public class RequestBuilder<TranscodeType> implements Cloneable {
} }
/** /**
* Returns a request builder to load the given {@link java.lang.String}. signature. * Returns a request builder to load the given {@link Bitmap}.
*
* <p>{@link Bitmap}s provided to this method become owned by Glide. The {@link Bitmap} may be
* recycled or re-used at any time. If you do not own the Bitmap or you need to continue to use
* the {@link Bitmap} after passing it in to Glide, consider passing a copy of the {@link Bitmap}
* to Glide instead. It's almost always better to allow Glide to load {@link Bitmap}s than
* pass {@link Bitmap}s into Glide. If you have a custom way to obtain {@link Bitmap}s that is
* not supported by Glide, consider registering a custom
* {@link com.bumptech.glide.load.model.ModelLoader} or
* {@link com.bumptech.glide.load.ResourceDecoder} instead.
*
* <p>The {@link DiskCacheStrategy} is set to {@link DiskCacheStrategy#NONE}. Using other
* strategies may result in undefined behavior.
*
* <p>In memory caching relies on Object equality. The contents of the {@link Bitmap}s are not
* compared.
*
* @see #load(Object)
*/
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable Bitmap bitmap) {
return loadGeneric(bitmap)
.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}
/**
* Returns a request builder to load the given {@link Drawable}.
*
* <p>{@link Drawable}s provided to this method become owned by Glide. They or {@link Bitmap}s
* they contain may be recycled or re-used at any time. If you do not own the {@link Drawable},
* do not pass it in to Glide. It's almost always better to allow Glide to load {@link Bitmap}s
* than pass {@link Bitmap}s into Glide. If you have a custom way to obtain {@link Bitmap}s that
* is not supported by Glide, consider registering a custom
* {@link com.bumptech.glide.load.model.ModelLoader} or
* {@link com.bumptech.glide.load.ResourceDecoder} instead.
*
* <p>The {@link DiskCacheStrategy} is set to {@link DiskCacheStrategy#NONE}. Using other
* strategies may result in undefined behavior.
*
* <p>In memory caching relies on Object equality. The contents of the {@link Drawable}s are not
* compared.
*
* @see #load(Object)
*/
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable Drawable drawable) {
return loadGeneric(drawable)
.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}
/**
* Returns a request builder to load the given {@link java.lang.String}.
* *
* <p> Note - this method caches data using only the given String as the cache key. If the data is * <p> Note - this method caches data using only the given String as the cache key. If the data is
* a Uri outside of your control, or you otherwise expect the data represented by the given String * a Uri outside of your control, or you otherwise expect the data represented by the given String
......
package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
import android.support.annotation.Nullable;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import java.io.IOException;
public final class UnitBitmapDecoder implements ResourceDecoder<Bitmap, Bitmap> {
private final BitmapPool bitmapPool;
public UnitBitmapDecoder(BitmapPool bitmapPool) {
this.bitmapPool = bitmapPool;
}
@Override
public boolean handles(Bitmap source, Options options) throws IOException {
return true;
}
@Nullable
@Override
public Resource<Bitmap> decode(Bitmap source, int width, int height, Options options)
throws IOException {
return new BitmapResource(source, bitmapPool);
}
}
package com.bumptech.glide.load.resource.drawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapDrawableResource;
/**
* Handles generic {@link Drawable} types where we may be uncertain of their size or type.
*/
final class DrawableResourceImpl extends DrawableResource<Drawable> {
@SuppressWarnings("unchecked")
public static Resource<Drawable> newInstance(Drawable drawable, BitmapPool bitmapPool) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
return (Resource<Drawable>) (Resource<? extends Drawable>)
new BitmapDrawableResource(bitmapDrawable, bitmapPool);
}
return new DrawableResourceImpl(drawable);
}
private DrawableResourceImpl(Drawable drawable) {
super(drawable);
}
@SuppressWarnings("unchecked")
@Override
public Class<Drawable> getResourceClass() {
return (Class<Drawable>) drawable.getClass();
}
@Override
public int getSize() {
// 4 bytes per pixel for ARGB_8888 Bitmaps is something of a reasonable approximation. If
// there are no intrinsic bounds, we can fall back just to 1.
return Math.max(1, drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight() * 4);
}
@Override
public void recycle() {
// Do nothing.
}
}
...@@ -3,7 +3,6 @@ package com.bumptech.glide.load.resource.drawable; ...@@ -3,7 +3,6 @@ package com.bumptech.glide.load.resource.drawable;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
...@@ -12,7 +11,6 @@ import com.bumptech.glide.load.Options; ...@@ -12,7 +11,6 @@ import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.ResourceDecoder; import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.engine.Resource; import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapDrawableResource;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
...@@ -56,17 +54,7 @@ public class ResourceDrawableDecoder implements ResourceDecoder<Uri, Drawable> { ...@@ -56,17 +54,7 @@ public class ResourceDrawableDecoder implements ResourceDecoder<Uri, Drawable> {
? context : getContextForPackage(source, packageName); ? context : getContextForPackage(source, packageName);
// We can't get a theme from another application. // We can't get a theme from another application.
Drawable drawable = DrawableDecoderCompat.getDrawable(toUse, resId); Drawable drawable = DrawableDecoderCompat.getDrawable(toUse, resId);
return getDrawableResource(drawable); return DrawableResourceImpl.newInstance(drawable, bitmapPool);
}
@SuppressWarnings("unchecked")
private Resource<Drawable> getDrawableResource(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
return (Resource<Drawable>) (Resource<? extends Drawable>)
new BitmapDrawableResource(bitmapDrawable, bitmapPool);
}
return new InternalDrawableResource(drawable);
} }
@NonNull @NonNull
...@@ -103,29 +91,4 @@ public class ResourceDrawableDecoder implements ResourceDecoder<Uri, Drawable> { ...@@ -103,29 +91,4 @@ public class ResourceDrawableDecoder implements ResourceDecoder<Uri, Drawable> {
} }
return result; return result;
} }
private static final class InternalDrawableResource extends DrawableResource<Drawable> {
InternalDrawableResource(Drawable drawable) {
super(drawable);
}
@SuppressWarnings("unchecked")
@Override
public Class<Drawable> getResourceClass() {
return (Class<Drawable>) drawable.getClass();
}
@Override
public int getSize() {
// 4 bytes per pixel for ARGB_8888 Bitmaps is something of a reasonable approximation. If
// there are no intrinsic bounds, we can fall back just to 1.
return Math.max(1, drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight() * 4);
}
@Override
public void recycle() {
// Do nothing.
}
}
} }
package com.bumptech.glide.load.resource.drawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import java.io.IOException;
/**
* Passes through a {@link Drawable} as a {@link Drawable} based {@link Resource}.
*/
public class UnitDrawableDecoder implements ResourceDecoder<Drawable, Drawable> {
private final BitmapPool bitmapPool;
public UnitDrawableDecoder(BitmapPool bitmapPool) {
this.bitmapPool = bitmapPool;
}
@Override
public boolean handles(Drawable source, Options options) throws IOException {
return true;
}
@Nullable
@Override
public Resource<Drawable> decode(Drawable source, int width, int height, Options options)
throws IOException {
return DrawableResourceImpl.newInstance(source, bitmapPool);
}
}
...@@ -3,8 +3,10 @@ package com.bumptech.glide; ...@@ -3,8 +3,10 @@ package com.bumptech.glide;
import static com.bumptech.glide.request.RequestOptions.decodeTypeOf; import static com.bumptech.glide.request.RequestOptions.decodeTypeOf;
import static com.bumptech.glide.request.RequestOptions.errorOf; import static com.bumptech.glide.request.RequestOptions.errorOf;
import static com.bumptech.glide.request.RequestOptions.placeholderOf; import static com.bumptech.glide.request.RequestOptions.placeholderOf;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA; import static org.mockito.Matchers.isA;
...@@ -70,6 +72,7 @@ import org.junit.After; ...@@ -70,6 +72,7 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
...@@ -554,6 +557,40 @@ public class GlideTest { ...@@ -554,6 +557,40 @@ public class GlideTest {
verify(target).onLoadFailed(eq(error)); verify(target).onLoadFailed(eq(error));
} }
@Test
public void testLoadBitmap_asBitmap() {
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
requestManager
.asBitmap()
.load(bitmap)
.into(target);
verify(target).onResourceReady(eq(bitmap), any(Transition.class));
}
@Test
public void testLoadBitmap_asDrawable() {
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
requestManager
.load(bitmap)
.into(target);
ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
verify(target).onResourceReady(captor.capture(), any(Transition.class));
BitmapDrawable drawable = (BitmapDrawable) captor.getValue();
assertThat(drawable.getBitmap()).isEqualTo(bitmap);
}
@Test
public void testLoadDrawable() {
Drawable drawable = new ColorDrawable(Color.RED);
requestManager
.load(drawable)
.into(target);
verify(target).onResourceReady(eq(drawable), any(Transition.class));
}
@Test @Test
public void testNullModelPrefersFallbackDrawable() { public void testNullModelPrefersFallbackDrawable() {
Drawable placeholder = new ColorDrawable(Color.GREEN); Drawable placeholder = new ColorDrawable(Color.GREEN);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册