From a23b64f5872138b0a5fa4c95be5dcf3f6f0942d8 Mon Sep 17 00:00:00 2001 From: Sam Judd Date: Wed, 9 Jul 2014 21:35:35 -0700 Subject: Add constant state to GifDrawable. --- .../bumptech/glide/load/resource/gif/GifData.java | 8 +- .../glide/load/resource/gif/GifDrawable.java | 94 +++++++++++++++++++--- .../glide/load/resource/gif/GifDataTest.java | 2 + .../glide/load/resource/gif/GifDrawableTest.java | 26 ++++++ 4 files changed, 115 insertions(+), 15 deletions(-) (limited to 'library') diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifData.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifData.java index 5d9494f4..3ddae458 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifData.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifData.java @@ -84,12 +84,8 @@ public class GifData { * the wrapped GIF. */ public GifDrawable getDrawable() { - GifDecoder gifDecoder = new GifDecoder(bitmapProvider); - gifDecoder.setData(gifId, header, data); - GifFrameManager frameManager = new GifFrameManager(context, gifDecoder, getFrameTransformation(), - targetWidth, targetHeight); - - GifDrawable result = new GifDrawable(gifDecoder, frameManager); + GifDrawable result = new GifDrawable(gifId, header, data, context, getFrameTransformation(), targetWidth, + targetHeight, bitmapProvider); drawables.add(result); return result; } diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawable.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawable.java index 5c0784c0..55edd294 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawable.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawable.java @@ -1,6 +1,8 @@ package com.bumptech.glide.load.resource.gif; import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorFilter; @@ -11,30 +13,47 @@ import android.graphics.drawable.Drawable; import android.os.Build; import com.bumptech.glide.gifdecoder.GifDecoder; +import com.bumptech.glide.gifdecoder.GifHeader; +import com.bumptech.glide.load.Transformation; /** * An animated {@link android.graphics.drawable.Drawable} that plays the frames of an animated GIF. */ public class GifDrawable extends Drawable implements Animatable, GifFrameManager.FrameCallback { - private final Paint paint; - private final GifFrameManager frameManager; - private int width; - private int height; + private final Paint paint = new Paint(); + private GifFrameManager frameManager; + private GifState state; + private int width = -1; + private int height = -1; private GifDecoder decoder; private boolean isRunning; private Bitmap currentFrame; private boolean isRecycled; - public GifDrawable(GifDecoder decoder, GifFrameManager frameManager) { + public GifDrawable(String id, GifHeader gifHeader, byte[] data, Context context, + Transformation frameTransformation, int targetWidth, int targetHeight, + GifDecoder.BitmapProvider bitmapProvider) { + this(new GifState(id, gifHeader, data, context, frameTransformation, targetWidth, targetHeight, + bitmapProvider)); + } + + private GifDrawable(GifState state) { + this.state = state; + this.decoder = new GifDecoder(state.bitmapProvider); + decoder.setData(state.id, state.gifHeader, state.data); + frameManager = new GifFrameManager(state.context, decoder, state.frameTransformation, state.targetWidth, + state.targetHeight); + } + + // For testing. + GifDrawable(GifDecoder decoder, GifFrameManager frameManager) { this.decoder = decoder; this.frameManager = frameManager; - width = -1; - height = -1; - - paint = new Paint(); + this.state = new GifState(null); } + @Override public void start() { if (!isRunning) { @@ -126,6 +145,11 @@ public class GifDrawable extends Drawable implements Animatable, GifFrameManager frameManager.getNextFrame(this); } + @Override + public ConstantState getConstantState() { + return state; + } + /** * Clears any resources for loading frames that are currently held on to by this object. */ @@ -137,4 +161,56 @@ public class GifDrawable extends Drawable implements Animatable, GifFrameManager boolean isRecycled() { return isRecycled; } + + static class GifState extends ConstantState { + String id; + GifHeader gifHeader; + byte[] data; + Context context; + Transformation frameTransformation; + int targetWidth; + int targetHeight; + GifDecoder.BitmapProvider bitmapProvider; + + public GifState(String id, GifHeader header, byte[] data, Context context, + Transformation frameTransformation, int targetWidth, int targetHeight, + GifDecoder.BitmapProvider provider) { + this.id = id; + gifHeader = header; + this.data = data; + this.context = context.getApplicationContext(); + this.frameTransformation = frameTransformation; + this.targetWidth = targetWidth; + this.targetHeight = targetHeight; + bitmapProvider = provider; + } + + public GifState(GifState original) { + if (original != null) { + id = original.id; + gifHeader = original.gifHeader; + data = original.data; + context = original.context; + frameTransformation = original.frameTransformation; + targetWidth = original.targetWidth; + targetHeight = original.targetHeight; + bitmapProvider = original.bitmapProvider; + } + } + + @Override + public Drawable newDrawable(Resources res) { + return super.newDrawable(res); + } + + @Override + public Drawable newDrawable() { + return new GifDrawable(this); + } + + @Override + public int getChangingConfigurations() { + return 0; + } + } } diff --git a/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDataTest.java b/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDataTest.java index b638e253..2baa9e57 100644 --- a/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDataTest.java +++ b/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDataTest.java @@ -1,10 +1,12 @@ package com.bumptech.glide.load.resource.gif; import android.graphics.Bitmap; + import com.bumptech.glide.gifdecoder.GifHeader; import com.bumptech.glide.load.Transformation; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.tests.GlideShadowLooper; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDrawableTest.java b/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDrawableTest.java index 7347b10e..c62df377 100644 --- a/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDrawableTest.java +++ b/library/src/test/java/com/bumptech/glide/load/resource/gif/GifDrawableTest.java @@ -5,14 +5,22 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; + import com.bumptech.glide.gifdecoder.GifDecoder; +import com.bumptech.glide.gifdecoder.GifHeader; +import com.bumptech.glide.load.Transformation; +import com.bumptech.glide.tests.GlideShadowLooper; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; @@ -25,6 +33,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(RobolectricTestRunner.class) +@Config(shadows = GlideShadowLooper.class) public class GifDrawableTest { private GifDecoder gifDecoder; private GifDrawable drawable; @@ -210,4 +219,21 @@ public class GifDrawableTest { assertTrue(drawable.isRecycled()); } + + @Test + public void testReturnsNonNullConstantState() { + assertNotNull(drawable.getConstantState()); + } + + @Test + public void testReturnsNewDrawableFromConstantState() { + GifHeader gifHeader = mock(GifHeader.class); + Transformation transformation = mock(Transformation.class); + GifDecoder.BitmapProvider provider = mock(GifDecoder.BitmapProvider.class); + drawable = new GifDrawable("fakeId", gifHeader, new byte[0], Robolectric.application, transformation, 100, 100, + provider); + + assertNotNull(drawable.getConstantState().newDrawable()); + assertNotNull(drawable.getConstantState().newDrawable(Robolectric.application.getResources())); + } } -- cgit v1.2.3