aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Newberger <alann@google.com>2014-12-03 10:47:03 -0800
committerAlan Newberger <alann@google.com>2014-12-03 10:47:03 -0800
commit617200ae32e6671631846ae0f840115c4463c8d4 (patch)
tree17fb77eadd24974e99a5b1a44df32f5ea81f1665
parent9dbd132bec874fdb47231ffe45d4df2b1ae05764 (diff)
parenta311d4835cdede5757e203d52a1bb5e707cfd989 (diff)
downloadglide-617200ae32e6671631846ae0f840115c4463c8d4.tar.gz
Merge tag 'v3.4.0' of https://github.com/bumptech/glide into ub-camera-haleakala
Change-Id: Ic290a947323184bfd15576a781bceb88258a5dd1
-rw-r--r--.travis.yml1
-rw-r--r--README.md6
-rw-r--r--build.gradle57
-rw-r--r--checkstyle.xml150
-rw-r--r--checkstyle_suppressions.xml12
-rw-r--r--glide/build.gradle106
-rw-r--r--glide/gradle.properties4
-rw-r--r--gradle.properties15
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin51017 -> 0 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xgradlew164
-rw-r--r--gradlew.bat90
-rw-r--r--library/build.gradle88
-rw-r--r--library/findbugs-exclude.xml35
-rw-r--r--library/gradle.properties3
-rw-r--r--library/pmd-ruleset.xml31
-rw-r--r--library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/BitmapTypeRequest.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/DownloadOptions.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/DrawableOptions.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java14
-rw-r--r--library/src/main/java/com/bumptech/glide/DrawableTypeRequest.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java31
-rw-r--r--library/src/main/java/com/bumptech/glide/GenericTranscodeRequest.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/GifRequestBuilder.java13
-rw-r--r--library/src/main/java/com/bumptech/glide/Glide.java24
-rw-r--r--library/src/main/java/com/bumptech/glide/GlideBuilder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/RequestManager.java15
-rw-r--r--library/src/main/java/com/bumptech/glide/load/ResourceDecoder.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/data/AssetPathFetcher.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/data/HttpUrlFetcher.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/data/LocalUriFetcher.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/DecodeJob.java91
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/Engine.java45
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/EngineJob.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/EngineResource.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/EngineRunnable.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/ResourceRecycler.java42
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/AttributeStrategy.java32
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPool.java8
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/LruBitmapPool.java12
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/SizeStrategy.java20
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/cache/LruResourceCache.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/executor/FifoPriorityThreadPoolExecutor.java30
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillIdleHandler.java91
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillRunner.java161
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFiller.java38
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillBitmapAttribute.java129
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillQueue.java12
-rw-r--r--library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillType.java172
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/FileLoader.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/GenericLoaderFactory.java27
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/ImageVideoModelLoader.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/ModelCache.java36
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/ModelLoader.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/ResourceLoader.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/StreamEncoder.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/StringLoader.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/UriLoader.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorFileLoader.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorResourceLoader.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorStringLoader.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorUriLoader.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java14
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/HttpUrlGlideUrlLoader.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/MediaStoreStreamLoader.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/StreamByteArrayLoader.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/StreamFileLoader.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/StreamResourceLoader.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/StreamStringLoader.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/StreamUriLoader.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/model/stream/StreamUrlLoader.java5
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/SimpleResource.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDecoder.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDrawableResource.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapResource.java22
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java53
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDataLoadProvider.java2
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDecoder.java11
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/GlideBitmapDrawable.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageHeaderParser.java12
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoBitmapDecoder.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoDataLoadProvider.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java27
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDataLoadProvider.java2
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDecoder.java9
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java73
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoBitmapDecoder.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/drawable/DrawableResource.java3
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/file/StreamFileDataLoadProvider.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifBitmapProvider.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawable.java20
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableLoadProvider.java7
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableTransformation.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java84
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameResourceDecoder.java5
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceDecoder.java25
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceEncoder.java2
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapper.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResource.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceDecoder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceEncoder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperTransformation.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/ImageVideoGifDrawableLoadProvider.java6
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapBytesTranscoder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapToGlideDrawableTranscoder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/transcode/GifBitmapWrapperDrawableTranscoder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/load/resource/transcode/GlideBitmapDrawableTranscoder.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/provider/LoadProvider.java2
-rw-r--r--library/src/main/java/com/bumptech/glide/request/GenericRequest.java9
-rw-r--r--library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeFactory.java72
-rw-r--r--library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java68
-rw-r--r--library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java72
-rw-r--r--library/src/main/java/com/bumptech/glide/request/animation/ViewAnimationFactory.java78
-rw-r--r--library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimation.java30
-rw-r--r--library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimationFactory.java34
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/ImageViewTargetFactory.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/PreloadTarget.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/SimpleTarget.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/SizeReadyCallback.java4
-rw-r--r--library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java1
-rw-r--r--library/src/main/java/com/bumptech/glide/signature/MediaStoreSignature.java12
-rw-r--r--library/src/main/java/com/bumptech/glide/util/ExceptionCatchingInputStream.java12
-rw-r--r--library/src/main/java/com/bumptech/glide/util/Util.java3
-rw-r--r--settings.gradle13
-rw-r--r--static/glide_logo.pngbin13002 -> 0 bytes
-rw-r--r--testutil/src/main/java/com/bumptech/glide/testutil/TestResourceUtil.java23
-rw-r--r--testutil/src/main/java/com/bumptech/glide/testutil/TestUtil.java37
-rw-r--r--third_party/disklrucache/README.md16
-rw-r--r--third_party/disklrucache/README.third_party6
-rw-r--r--third_party/disklrucache/build.gradle16
-rw-r--r--third_party/disklrucache/checkstyle.xml129
-rw-r--r--third_party/disklrucache/gradle/wrapper/gradle-wrapper.jarbin51348 -> 0 bytes
-rw-r--r--third_party/disklrucache/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xthird_party/disklrucache/gradlew164
-rw-r--r--third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/DiskLruCache.java12
-rw-r--r--third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/StrictLineReader.java4
-rw-r--r--third_party/gif_decoder/build.gradle22
-rw-r--r--third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifDecoder.java77
-rw-r--r--third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifHeaderParser.java29
-rw-r--r--third_party/gif_encoder/build.gradle12
-rw-r--r--third_party/gif_encoder/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java16
149 files changed, 1343 insertions, 1958 deletions
diff --git a/.travis.yml b/.travis.yml
index 14fe933d..c1a2a27c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,3 +9,4 @@ script: 'travis_retry ./gradlew build --parallel'
after_success:
- scripts/travis-sonatype-publish.sh
+- ./gradlew jacocoTestReport coveralls
diff --git a/README.md b/README.md
index 54475fb0..36297b7d 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ repositories {
dependencies {
compile 'com.github.bumptech.glide:glide:3.3.+'
- compile 'com.android.support:support-v4:19.0.0'
+ compile 'com.android.support:support-v4:19.1.0'
}
```
@@ -171,6 +171,10 @@ public void onCreate() {
}
```
+Android SDK Version
+-------------------
+Glide requires a minimum sdk version of 10.
+
License
-------
BSD, part MIT and Apache 2.0. See LICENSE file for details.
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 797a9ede..00000000
--- a/build.gradle
+++ /dev/null
@@ -1,57 +0,0 @@
-buildscript {
- repositories {
- jcenter()
- // TODO: remove this when robolectric 2.4 is released.
- maven {
- url 'https://oss.sonatype.org/content/repositories/snapshots'
- }
- }
-
- dependencies {
- classpath 'org.robolectric:robolectric-gradle-plugin:0.12.+'
- classpath 'com.android.tools.build:gradle:0.13.+'
- }
-}
-
-subprojects { project ->
- repositories {
- jcenter()
- // TODO: remove this when robolectric 2.4 is released.
- maven {
- url 'https://oss.sonatype.org/content/repositories/snapshots'
- }
- }
-
- apply plugin: 'checkstyle'
-
- checkstyle {
- configFile = new File(rootDir, 'checkstyle.xml')
- }
-
- task checkstyle(type: Checkstyle) {
- source 'src'
- include '**/*.java'
- exclude '**/gen/**'
-
- // empty classpath
- classpath = files()
- }
-
- afterEvaluate {
- if (project.tasks.findByName('check')) {
- check.dependsOn('checkstyle')
- }
- }
-
- gradle.projectsEvaluated {
- tasks.withType(JavaCompile) {
- if (!name.contains('Test')) {
- options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
- }
- }
- }
-}
-
-task wrapper(type: Wrapper) {
- gradleVersion = '2.1'
-}
diff --git a/checkstyle.xml b/checkstyle.xml
deleted file mode 100644
index bdf87125..00000000
--- a/checkstyle.xml
+++ /dev/null
@@ -1,150 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-<module name="Checker">
- <module name="FileLength"/>
- <module name="FileTabCharacter"/>
-
- <module name="SuppressionFilter">
- <property name="file" value="checkstyle_suppressions.xml" />
- </module>
-
- <!-- Trailing spaces -->
- <module name="RegexpSingleline">
- <property name="format" value="\s+$"/>
- <property name="message" value="Line has trailing spaces."/>
- </module>
-
- <!-- Space after 'for' and 'if' -->
- <module name="RegexpSingleline">
- <property name="format" value="^\s*(for|if)\b[^ ]"/>
- <property name="message" value="Space needed before opening parenthesis."/>
- </module>
-
- <!-- For each spacing -->
- <module name="RegexpSingleline">
- <property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
- <property name="message" value="Space needed around ':' character."/>
- </module>
-
- <module name="TreeWalker">
- <!-- Checks for uncommented main() methods (debugging leftovers). -->
- <!-- Checks that long constants are defined with an upper ell. -->
- <!-- See http://checkstyle.sourceforge.net/config_misc.html#UpperEll -->
- <module name="UpperEll" />
-
- <!-- Checks the style of array type definitions. -->
- <!-- See http://checkstyle.sourceforge.net/config_misc.html#ArrayTypeStyle -->
- <module name="ArrayTypeStyle" />
-
- <!-- Checks that the outer type name and the file name match. -->
- <!-- See http://checkstyle.sourceforge.net/config_misc.html#OuterTypeFilename -->
- <module name="OuterTypeFilename" />
-
- <!-- Validates Javadoc comments to help ensure they are well formed. -->
- <!-- See http://checkstyle.sourceforge.net/config_javadoc.html#JavadocStyle -->
- <module name="JavadocStyle" />
- <module name="JavadocType">
- <property name="scope" value="public"/>
- </module>
-
- <!-- Each of these naming modules validates identifiers for particular
- code elements. -->
- <!-- See http://checkstyle.sourceforge.net/config_naming.html -->
- <module name="ConstantName">
- <property name="format" value="^[A-Z][A-Z0-9\$]*(_[A-Z0-9\$]+)*$" />
- </module>
- <module name="LocalFinalVariableName" />
- <module name="LocalVariableName" />
- <module name="MemberName">
- <property name="format" value="^[a-z][a-zA-Z0-9_\$]*$" />
- </module>
- <module name="MethodName" />
- <module name="PackageName" />
- <module name="ParameterName" />
- <module name="StaticVariableName" />
- <module name="TypeName" />
-
- <module name="TrailingComment" />
-
- <!-- Checks for imports. -->
- <!-- See http://checkstyle.sourceforge.net/config_imports.html -->
- <module name="AvoidStarImport"/>
- <module name="RedundantImport"/>
- <module name="UnusedImports"/>
- <!-- Default sun.* packages -->
- <module name="IllegalImport">
- <property name="illegalPkgs" value="sun" />
- <message key="import.illegal" value="Import from illegal package - {0}. Programs that contain direct calls to the sun.* packages are not 100% Pure Java." />
- </module>
- <!-- Prevent importing JUnit 3 classes and Assert methods -->
- <module name="IllegalImport">
- <property name="illegalPkgs" value="junit" />
- <message key="import.illegal" value="Import from illegal package - {0}. Tests are written in JUnit 4, use org.junit.* equivalents." />
- </module>
- <!-- Prevent importing Mockito matchers directly -->
- <module name="IllegalImport">
- <property name="illegalPkgs" value="org.mockito.internal" />
- <message key="import.illegal" value="Import from illegal package - {0}. Use org.mockito.Matchers to instantiate argument matchers; or org.hamcrest.Matchers for assertThat." />
- </module>
-
- <!-- Checks for whitespace. -->
- <!-- See http://checkstyle.sourceforge.net/config_whitespace.html -->
- <module name="GenericWhitespace" />
- <module name="MethodParamPad" />
- <module name="NoWhitespaceAfter">
- <property name="tokens"
- value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS" />
- </module>
- <module name="NoWhitespaceBefore" />
- <module name="OperatorWrap" />
- <module name="ParenPad" />
- <module name="TypecastParenPad" />
- <module name="WhitespaceAfter" />
- <module name="WhitespaceAround" />
-
-
- <!-- Modifier Checks. -->
- <!-- See http://checkstyle.sourceforge.net/config_modifier.html -->
- <module name="ModifierOrder" />
-
- <!-- Checks for blocks. -->
- <!-- See http://checkstyle.sourceforge.net/config_blocks.html -->
- <module name="AvoidNestedBlocks" />
- <module name="EmptyBlock" >
- <property name="option" value="text"/>
- </module>
- <module name="NeedBraces"/>
-
- <module name="LeftCurly" />
- <module name="RightCurly">
- <property name="tokens"
- value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_ELSE" />
- </module>
-
- <!-- Checks for common coding problems. -->
- <!-- See http://checkstyle.sourceforge.net/config_coding.html -->
- <module name="CovariantEquals" />
- <module name="DefaultComesLast" />
- <module name="EmptyStatement" />
- <module name="EqualsHashCode" />
- <module name="NoClone" />
- <module name="NoFinalizer" />
- <module name="OneStatementPerLine" />
- <module name="RedundantThrows" >
- <property name="suppressLoadErrors" value="true" />
- </module>
- <module name="IllegalInstantiation"/>
- <module name="SimplifyBooleanExpression" />
- <module name="SimplifyBooleanReturn" />
- <module name="StringLiteralEquality" />
- <module name="UnnecessaryParentheses" />
- <module name="LineLength">
- <property name="max" value="120" />
- </module>
-
- <!-- Checks for class design. -->
- <!-- See http://checkstyle.sourceforge.net/config_design.html -->
- <module name="FinalClass" />
- <module name="InterfaceIsType" />
- </module>
-</module>
diff --git a/checkstyle_suppressions.xml b/checkstyle_suppressions.xml
deleted file mode 100644
index 1d8da750..00000000
--- a/checkstyle_suppressions.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE suppressions PUBLIC
- "-//Puppy Crawl//DTD Suppressions 1.1//EN"
- "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
-
-<suppressions>
- <suppress files=".*[/\\]library[/\\]src[/\\]androidTest[/\\].*" checks="Javadoc.*"/>
- <suppress files=".*[/\\]gif_encoder[/\\].*" checks=".*"/>
- <suppress files=".*RequestBuilder.java|ChildLoadProvider.java" checks="NoClone" />
-</suppressions>
-
diff --git a/glide/build.gradle b/glide/build.gradle
deleted file mode 100644
index 410a1df7..00000000
--- a/glide/build.gradle
+++ /dev/null
@@ -1,106 +0,0 @@
-apply plugin: 'java'
-
-evaluationDependsOn(':third_party:gif_decoder')
-evaluationDependsOn(':third_party:disklrucache')
-evaluationDependsOn(':library')
-
-def getAndroidSdkDirectory() {
- project(':library').android.sdkDirectory
-}
-
-def getAndroidCompileSdkVersion() {
- project(':library').android.compileSdkVersion
-}
-
-def getInternalAndroidProjects() {
- [':third_party:gif_decoder', ':third_party:gif_encoder', ':library'].collect { project(it) }
-}
-def getInternalJavaProjects() {
- [':third_party:disklrucache'].collect { project(it) }
-}
-
-def getAllInternalProjects() {
- getInternalAndroidProjects() + getInternalJavaProjects()
-}
-
-def getReleaseVariantAndroidProjects() {
- getAndroidLibraryVariants('release')
-}
-
-def getAndroidLibraryVariants(variantName) {
- getInternalAndroidProjects().collect { project ->
- project.android.libraryVariants.findAll { type ->
- type.buildType.name.equalsIgnoreCase(variantName)
- }
- }.sum()
-}
-
-def getSourceFilesForVariant(variantName) {
- getAndroidLibraryVariants(variantName).collect { it.javaCompile.source } +
- getInternalJavaProjects().collect { it.sourceSets.main.allJava }
-}
-
-def getAndroidJar() {
- "${getAndroidSdkDirectory()}/platforms/${getAndroidCompileSdkVersion()}/android.jar"
-}
-
-// Generate javadocs and sources containing batched documentation and sources for all internal projects.
-['release', 'debug'].each { variantName ->
-
- task("${variantName}SourceJar", type: Jar) {
- from getSourceFilesForVariant(variantName)
- }
-
- def javadocTask = task("${variantName}Javadoc", type: Javadoc) {
- source = getSourceFilesForVariant(variantName)
-
- classpath = files(getAndroidLibraryVariants(variantName).collect {
- files(it.javaCompile.classpath.files, getAndroidJar())
- })
- classpath += getInternalJavaProjects().collect { files(it.configurations.compile) }
-
- options {
- links("http://docs.oracle.com/javase/7/docs/api/")
- linksOffline("http://d.android.com/reference", "${getAndroidSdkDirectory()}/docs/reference")
- }
-
- exclude '**/BuildConfig.java'
- exclude '**/R.java'
- }
-
- def cleanJavadocTask = task("clean${variantName.capitalize()}Javadoc", type: Delete) {
- delete javadocTask.destinationDir
- }
- clean.dependsOn(cleanJavadocTask)
-
- def javadocJarTask = task("${variantName}JavadocJar", type: Jar) {
- from javadocTask.destinationDir
- }
- javadocJarTask.dependsOn(javadocTask)
-}
-
-jar {
- from files(
- getReleaseVariantAndroidProjects().collect { variant ->
- variant.javaCompile.destinationDir
- }
- )
- exclude "**/R.class"
- exclude "**/BuildConfig.class"
- from files(getInternalJavaProjects().collect { it.sourceSets.main.output })
-}
-
-getAllInternalProjects().each { project ->
- jar.dependsOn(project.build)
-}
-
-artifacts {
- archives releaseJavadocJar {
- classifier 'javadoc'
- }
- archives releaseSourceJar {
- classifier 'sources'
- }
-}
-
-apply from: "$rootProject.projectDir/scripts/upload.gradle" \ No newline at end of file
diff --git a/glide/gradle.properties b/glide/gradle.properties
deleted file mode 100644
index f205a7f3..00000000
--- a/glide/gradle.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-POM_NAME=Glide
-POM_ARTIFACT_ID=glide
-POM_PACKAGING=jar
-
diff --git a/gradle.properties b/gradle.properties
deleted file mode 100644
index cd214548..00000000
--- a/gradle.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-VERSION_NAME=3.4.0-SNAPSHOT
-VERSION_MAJOR=3
-VERSION_MINOR=4
-VERSION_PATCH=0
-VERSION_CODE=7
-GROUP=com.github.bumptech.glide
-
-POM_DESCRIPTION=A fast and efficient image loading library for Android focused on smooth scrolling.
-POM_URL=https://github.com/bumptech/glide
-POM_SCM_URL=https://github.com/bumptech/glide
-POM_SCM_CONNECTION=scm:git@github.com:bumptech/glide.git
-POM_SCM_DEV_CONNECTION=scm:git@github.com:bumptech/glide.git
-POM_DEVELOPER_ID=sjudd
-POM_DEVELOPER_NAME=Sam Judd
-POM_DEVELOPER_EMAIL=judds@google.com
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 3d0dee6e..00000000
--- a/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 53a7b2a7..00000000
--- a/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Fri Sep 19 07:33:32 PDT 2014
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-bin.zip
diff --git a/gradlew b/gradlew
deleted file mode 100755
index 91a7e269..00000000
--- a/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
deleted file mode 100644
index aec99730..00000000
--- a/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/library/build.gradle b/library/build.gradle
deleted file mode 100644
index 66c86131..00000000
--- a/library/build.gradle
+++ /dev/null
@@ -1,88 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: 'robolectric'
-apply plugin: 'maven'
-apply plugin: 'findbugs'
-apply plugin: 'pmd'
-
-findbugs {
- toolVersion = "2.0.3"
-}
-
-dependencies {
- compile project(':third_party:gif_decoder')
- compile project(':third_party:gif_encoder')
- compile project(':third_party:disklrucache')
- compile 'com.android.support:support-v4:19.1.+'
-
- androidTestCompile 'org.hamcrest:hamcrest-core:1.3'
- androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
- androidTestCompile 'junit:junit:4.11'
- androidTestCompile 'org.mockito:mockito-all:1.9.5'
- androidTestCompile 'org.robolectric:robolectric:2.4-SNAPSHOT'
- // TODO: increase this to 2.0.+ when we compile against Java 7.
- androidTestCompile 'com.squareup.okhttp:mockwebserver:1.2.+'
-}
-
-android {
- compileSdkVersion 19
- buildToolsVersion '19.1.0'
-
- defaultConfig {
- applicationId 'com.bumptech.glide'
- minSdkVersion 10
-
- targetSdkVersion 19
- versionCode = VERSION_CODE
- versionName = VERSION_NAME
- }
-}
-
-afterEvaluate {
- task findbugs(type: FindBugs, dependsOn: assembleDebug) {
-
- description 'Run findbugs'
- group 'verification'
-
- classes = fileTree('build/intermediates/classes/debug/')
- source = fileTree('src/main/java')
- classpath = files(project.configurations.compile.asPath)
-
- effort = 'max'
-
- excludeFilter = file("findbugs-exclude.xml")
-
- reports {
- xml.enabled = false
- html.enabled = true
- }
- }
-
- findbugsTestDebug {
- enabled = false
- }
-
- check.dependsOn('findbugs')
-
- task pmd(type: Pmd) {
-
- description 'Run pmd'
- group 'verification'
-
- // If ruleSets is not empty, it seems to contain some
- // defaults which override rules in the ruleset file...
- ruleSets = []
- ruleSetFiles = files('pmd-ruleset.xml')
- source = fileTree('src/main/java')
-
- reports {
- xml.enabled = false
- html.enabled = true
- }
- }
-
- pmdTestDebug {
- enabled = false
- }
-
- check.dependsOn('pmd')
-}
diff --git a/library/findbugs-exclude.xml b/library/findbugs-exclude.xml
deleted file mode 100644
index eff7240f..00000000
--- a/library/findbugs-exclude.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<FindBugsFilter>
-
- <Match>
- <Class name="~.*R\$.*"/>
- </Match>
- <Match>
- <Class name="~.*Manifest\$.*"/>
- </Match>
-
- <!-- BytesResource is the wrapper that is given control of the data. -->
- <Match>
- <Class name="com.bumptech.glide.load.resource.bytes.BytesResource" />
- <Method name="get" />
- <Bug pattern="EI_EXPOSE_REP" />
- </Match>
-
- <!-- We would rather expose the internal bytes than box or copy them. -->
- <Match>
- <Class name="com.bumptech.glide.load.resource.bytes.BytesResource" />
- <Bug pattern="EI_EXPOSE_REP2" />
- </Match>
-
- <!-- Byte array fetcher just wraps a byte array to return an InputStream, data is not mutated. -->
- <Match>
- <Class name="com.bumptech.glide.load.data.ByteArrayFetcher" />
- <Bug pattern="EI_EXPOSE_REP2" />
- </Match>
-
- <!-- RecyclableBufferedInputStream safely re-uses pooled byte arrays -->
- <Match>
- <Class name="com.bumptech.glide.load.resource.bitmap.RecyclableBufferedInputStream" />
- <Bug pattern="EI_EXPOSE_REP2" />
- </Match>
-
-</FindBugsFilter>
diff --git a/library/gradle.properties b/library/gradle.properties
deleted file mode 100644
index 6f3b8429..00000000
--- a/library/gradle.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-POM_NAME=Glide Library
-POM_ARTIFACT_ID=library
-POM_PACKAGING=aar
diff --git a/library/pmd-ruleset.xml b/library/pmd-ruleset.xml
deleted file mode 100644
index 94220cb6..00000000
--- a/library/pmd-ruleset.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
-<ruleset name="PMD.rul" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
-
- <description>This ruleset was created from PMD.rul</description>
-
- <rule ref="rulesets/java/basic.xml" >
- <exclude name="AvoidBranchingStatementAsLastInLoop" />
- </rule>
- <rule ref="rulesets/java/braces.xml" />
- <rule ref="rulesets/java/strings.xml" />
- <rule ref="rulesets/java/unusedcode.xml" />
-
- <rule ref="rulesets/java/design.xml" >
- <exclude name="ConfusingTernary" />
- <exclude name="EmptyMethodInAbstractClassShouldBeAbstract" />
- <exclude name="AvoidSynchronizedAtMethodLevel" />
-
- <!-- This check breaks on double checked locking which is safe in Java 6/7 -->
- <exclude name="NonThreadSafeSingleton" />
-
- <!-- TODO: Fix these -->
- <exclude name="AvoidReassigningParameters" />
- <exclude name="GodClass" />
- </rule>
-
- <rule ref="rulesets/java/empty.xml/EmptyCatchBlock" message="Commented blocks are ok">
- <properties>
- <property name="allowCommentedBlocks" value="true" />
- </properties>
- </rule>
-</ruleset>
diff --git a/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java b/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java
index 15b4ca85..07e7c4ab 100644
--- a/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/BitmapRequestBuilder.java
@@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable;
import android.os.ParcelFileDescriptor;
import android.view.animation.Animation;
import android.widget.ImageView;
+
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Key;
@@ -391,7 +392,7 @@ public class BitmapRequestBuilder<ModelType, TranscodeType>
*/
@Override
public BitmapRequestBuilder<ModelType, TranscodeType> listener(
- RequestListener<ModelType, TranscodeType> requestListener) {
+ RequestListener<? super ModelType, TranscodeType> requestListener) {
super.listener(requestListener);
return this;
}
diff --git a/library/src/main/java/com/bumptech/glide/BitmapTypeRequest.java b/library/src/main/java/com/bumptech/glide/BitmapTypeRequest.java
index 485b10fd..8e2b227c 100644
--- a/library/src/main/java/com/bumptech/glide/BitmapTypeRequest.java
+++ b/library/src/main/java/com/bumptech/glide/BitmapTypeRequest.java
@@ -2,6 +2,7 @@ package com.bumptech.glide;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.load.model.ImageVideoModelLoader;
import com.bumptech.glide.load.model.ImageVideoWrapper;
import com.bumptech.glide.load.model.ModelLoader;
diff --git a/library/src/main/java/com/bumptech/glide/DownloadOptions.java b/library/src/main/java/com/bumptech/glide/DownloadOptions.java
index dc4c73ba..ae472c85 100644
--- a/library/src/main/java/com/bumptech/glide/DownloadOptions.java
+++ b/library/src/main/java/com/bumptech/glide/DownloadOptions.java
@@ -21,8 +21,8 @@ interface DownloadOptions {
* Loads the original unmodified data into the cache and returns a {@link java.util.concurrent.Future} that can be
* used to retrieve the cache File containing the data.
*
- * @param width The width to use to fetch the data.
- * @param height The height to use to fetch the data.
+ * @param width The width in pixels to use to fetch the data.
+ * @param height The height in pixels to use to fetch the data.
* @return A {@link java.util.concurrent.Future} that can be used to retrieve the cache File containing the data.
*/
FutureTarget<File> downloadOnly(int width, int height);
diff --git a/library/src/main/java/com/bumptech/glide/DrawableOptions.java b/library/src/main/java/com/bumptech/glide/DrawableOptions.java
index 74e7eae9..ebc1aa5c 100644
--- a/library/src/main/java/com/bumptech/glide/DrawableOptions.java
+++ b/library/src/main/java/com/bumptech/glide/DrawableOptions.java
@@ -41,6 +41,7 @@ interface DrawableOptions {
* asked to start an animation using a single {@link android.view.animation.Animation} object which results in
* views animating repeatedly. Use {@link #crossFade(int, int)}} instead, or be sure to call this method once
* per call to {@link com.bumptech.glide.GenericRequestBuilder#load(Object)} to avoid re-using animation objects.
+ * Scheduled to be removed in Glide 4.0.
* @param animation The Animation to use if no placeholder is set.
* @param duration The duration of the cross fade animation.
* @return This request builder.
diff --git a/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java b/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java
index 78802765..845a01e8 100644
--- a/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java
@@ -5,6 +5,7 @@ import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.animation.Animation;
import android.widget.ImageView;
+
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.ResourceDecoder;
@@ -21,7 +22,7 @@ import com.bumptech.glide.manager.Lifecycle;
import com.bumptech.glide.manager.RequestTracker;
import com.bumptech.glide.provider.LoadProvider;
import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.animation.DrawableCrossFadeViewAnimation;
+import com.bumptech.glide.request.animation.DrawableCrossFadeFactory;
import com.bumptech.glide.request.animation.ViewPropertyAnimation;
import com.bumptech.glide.request.target.Target;
@@ -242,7 +243,7 @@ public class DrawableRequestBuilder<ModelType>
* {@inheritDoc}
*/
public final DrawableRequestBuilder<ModelType> crossFade() {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GlideDrawable>());
+ super.animate(new DrawableCrossFadeFactory<GlideDrawable>());
return this;
}
@@ -250,7 +251,7 @@ public class DrawableRequestBuilder<ModelType>
* {@inheritDoc}
*/
public DrawableRequestBuilder<ModelType> crossFade(int duration) {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GlideDrawable>(duration));
+ super.animate(new DrawableCrossFadeFactory<GlideDrawable>(duration));
return this;
}
@@ -259,7 +260,7 @@ public class DrawableRequestBuilder<ModelType>
*/
@Deprecated
public DrawableRequestBuilder<ModelType> crossFade(Animation animation, int duration) {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GlideDrawable>(animation, duration));
+ super.animate(new DrawableCrossFadeFactory<GlideDrawable>(animation, duration));
return this;
}
@@ -267,7 +268,7 @@ public class DrawableRequestBuilder<ModelType>
* {@inheritDoc}
*/
public DrawableRequestBuilder<ModelType> crossFade(int animationId, int duration) {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GlideDrawable>(context, animationId,
+ super.animate(new DrawableCrossFadeFactory<GlideDrawable>(context, animationId,
duration));
return this;
}
@@ -350,7 +351,8 @@ public class DrawableRequestBuilder<ModelType>
* {@inheritDoc}
*/
@Override
- public DrawableRequestBuilder<ModelType> listener(RequestListener<ModelType, GlideDrawable> requestListener) {
+ public DrawableRequestBuilder<ModelType> listener(
+ RequestListener<? super ModelType, GlideDrawable> requestListener) {
super.listener(requestListener);
return this;
}
diff --git a/library/src/main/java/com/bumptech/glide/DrawableTypeRequest.java b/library/src/main/java/com/bumptech/glide/DrawableTypeRequest.java
index 84d3a273..ee67f1a3 100644
--- a/library/src/main/java/com/bumptech/glide/DrawableTypeRequest.java
+++ b/library/src/main/java/com/bumptech/glide/DrawableTypeRequest.java
@@ -2,6 +2,7 @@ package com.bumptech.glide;
import android.content.Context;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.load.model.ImageVideoModelLoader;
import com.bumptech.glide.load.model.ImageVideoWrapper;
import com.bumptech.glide.load.model.ModelLoader;
diff --git a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
index 84b1828f..13319d73 100644
--- a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
@@ -4,7 +4,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.animation.Animation;
import android.widget.ImageView;
-import com.bumptech.glide.signature.EmptySignature;
+
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.MultiTransformation;
@@ -27,10 +27,12 @@ import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.ThumbnailRequestCoordinator;
import com.bumptech.glide.request.animation.GlideAnimationFactory;
import com.bumptech.glide.request.animation.NoAnimation;
-import com.bumptech.glide.request.animation.ViewAnimation;
+import com.bumptech.glide.request.animation.ViewAnimationFactory;
import com.bumptech.glide.request.animation.ViewPropertyAnimation;
+import com.bumptech.glide.request.animation.ViewPropertyAnimationFactory;
import com.bumptech.glide.request.target.PreloadTarget;
import com.bumptech.glide.request.target.Target;
+import com.bumptech.glide.signature.EmptySignature;
import com.bumptech.glide.util.Util;
import java.io.File;
@@ -60,7 +62,7 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
private boolean isModelSet;
private int placeholderId;
private int errorId;
- private RequestListener<ModelType, TranscodeType> requestListener;
+ private RequestListener<? super ModelType, TranscodeType> requestListener;
private Float thumbSizeMultiplier;
private GenericRequestBuilder<?, ?, ?, TranscodeType> thumbnailRequestBuilder;
private Float sizeMultiplier = 1f;
@@ -367,7 +369,7 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
* @return This request builder.
*/
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(int animationId) {
- return animate(new ViewAnimation.ViewAnimationFactory<TranscodeType>(context, animationId));
+ return animate(new ViewAnimationFactory<TranscodeType>(context, animationId));
}
/**
@@ -380,13 +382,14 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
* @deprecated If this builder is used for multiple loads, using this method will result in multiple view's being
* asked to start an animation using a single {@link android.view.animation.Animation} object which results in
* views animating repeatedly. Use {@link #animate(int)} or
- * {@link #animate(com.bumptech.glide.request.animation.ViewPropertyAnimation.Animator)}.
+ * {@link #animate(com.bumptech.glide.request.animation.ViewPropertyAnimation.Animator)}. Scheduled to be removed in
+ * Glide 4.0.
* @param animation The animation to run
* @return This request builder.
*/
@Deprecated
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(Animation animation) {
- return animate(new ViewAnimation.ViewAnimationFactory<TranscodeType>(animation));
+ return animate(new ViewAnimationFactory<TranscodeType>(animation));
}
/**
@@ -399,7 +402,7 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
*/
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(
ViewPropertyAnimation.Animator animator) {
- return animate(new ViewPropertyAnimation.ViewPropertyAnimationFactory<TranscodeType>(animator));
+ return animate(new ViewPropertyAnimationFactory<TranscodeType>(animator));
}
GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> animate(
@@ -474,7 +477,7 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
* @return This request builder.
*/
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> listener(
- RequestListener<ModelType, TranscodeType> requestListener) {
+ RequestListener<? super ModelType, TranscodeType> requestListener) {
this.requestListener = requestListener;
return this;
@@ -502,8 +505,8 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
* thumbnails, and should only be used when you both need a very specific sized image and when it is impossible or
* impractical to return that size from {@link Target#getSize(com.bumptech.glide.request.target.SizeReadyCallback)}.
*
- * @param width The width to use to load the resource.
- * @param height The height to use to load the resource.
+ * @param width The width in pixels to use to load the resource.
+ * @param height The height in pixels to use to load the resource.
* @return This request builder.
*/
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> override(int width, int height) {
@@ -651,10 +654,10 @@ public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeT
/**
* Returns a future that can be used to do a blocking get on a background thread.
*
- * @param width The desired width (note this will be overriden by {@link #override(int, int)} if
- * previously called.
- * @param height The desired height (note this will be overriden by {@link #override(int, int)}}
- * if previously called.
+ * @param width The desired width in pixels (note this will be overriden by {@link #override(int, int)} if
+ * previously called).
+ * @param height The desired height in pixels (note this will be overriden by {@link #override(int, int)}}
+ * if previously called).
*
* @see Glide#clear(com.bumptech.glide.request.FutureTarget)
*
diff --git a/library/src/main/java/com/bumptech/glide/GenericTranscodeRequest.java b/library/src/main/java/com/bumptech/glide/GenericTranscodeRequest.java
index 9c0b4efa..ca629236 100644
--- a/library/src/main/java/com/bumptech/glide/GenericTranscodeRequest.java
+++ b/library/src/main/java/com/bumptech/glide/GenericTranscodeRequest.java
@@ -1,6 +1,7 @@
package com.bumptech.glide;
import android.content.Context;
+
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
diff --git a/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java b/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java
index ffde6fe1..474f2e7c 100644
--- a/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/GifRequestBuilder.java
@@ -3,6 +3,7 @@ package com.bumptech.glide;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.animation.Animation;
+
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.ResourceDecoder;
@@ -15,7 +16,7 @@ import com.bumptech.glide.load.resource.gif.GifDrawableTransformation;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import com.bumptech.glide.provider.LoadProvider;
import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.animation.DrawableCrossFadeViewAnimation;
+import com.bumptech.glide.request.animation.DrawableCrossFadeFactory;
import com.bumptech.glide.request.animation.ViewPropertyAnimation;
import java.io.File;
@@ -229,7 +230,7 @@ public class GifRequestBuilder<ModelType>
*/
@Override
public GifRequestBuilder<ModelType> crossFade() {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GifDrawable>());
+ super.animate(new DrawableCrossFadeFactory<GifDrawable>());
return this;
}
@@ -238,7 +239,7 @@ public class GifRequestBuilder<ModelType>
*/
@Override
public GifRequestBuilder<ModelType> crossFade(int duration) {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GifDrawable>(duration));
+ super.animate(new DrawableCrossFadeFactory<GifDrawable>(duration));
return this;
}
@@ -248,7 +249,7 @@ public class GifRequestBuilder<ModelType>
@Deprecated
@Override
public GifRequestBuilder<ModelType> crossFade(Animation animation, int duration) {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GifDrawable>(animation, duration));
+ super.animate(new DrawableCrossFadeFactory<GifDrawable>(animation, duration));
return this;
}
@@ -257,7 +258,7 @@ public class GifRequestBuilder<ModelType>
*/
@Override
public GifRequestBuilder<ModelType> crossFade(int animationId, int duration) {
- super.animate(new DrawableCrossFadeViewAnimation.DrawableCrossFadeFactory<GifDrawable>(context, animationId,
+ super.animate(new DrawableCrossFadeFactory<GifDrawable>(context, animationId,
duration));
return this;
}
@@ -341,7 +342,7 @@ public class GifRequestBuilder<ModelType>
*/
@Override
public GifRequestBuilder<ModelType> listener(
- RequestListener<ModelType, GifDrawable> requestListener) {
+ RequestListener<? super ModelType, GifDrawable> requestListener) {
super.listener(requestListener);
return this;
}
diff --git a/library/src/main/java/com/bumptech/glide/Glide.java b/library/src/main/java/com/bumptech/glide/Glide.java
index 905c3a5e..5439a42a 100644
--- a/library/src/main/java/com/bumptech/glide/Glide.java
+++ b/library/src/main/java/com/bumptech/glide/Glide.java
@@ -15,12 +15,13 @@ import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
+
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.Engine;
-import com.bumptech.glide.load.engine.prefill.PreFillBitmapAttribute;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
-import com.bumptech.glide.load.engine.prefill.BitmapPreFiller;
import com.bumptech.glide.load.engine.cache.MemoryCache;
+import com.bumptech.glide.load.engine.prefill.BitmapPreFiller;
+import com.bumptech.glide.load.engine.prefill.PreFillType;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.ImageVideoWrapper;
@@ -82,7 +83,7 @@ public class Glide {
private static final String TAG = "Glide";
private static volatile Glide glide;
- private final GenericLoaderFactory loaderFactory = new GenericLoaderFactory();
+ private final GenericLoaderFactory loaderFactory;
private final Engine engine;
private final BitmapPool bitmapPool;
private final MemoryCache memoryCache;
@@ -188,8 +189,9 @@ public class Glide {
this.bitmapPool = bitmapPool;
this.memoryCache = memoryCache;
this.decodeFormat = decodeFormat;
+ loaderFactory = new GenericLoaderFactory(context);
mainHandler = new Handler(Looper.getMainLooper());
- bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool);
+ bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);
dataLoadProviderRegistry = new DataLoadProviderRegistry();
@@ -206,7 +208,7 @@ public class Glide {
dataLoadProviderRegistry.register(ImageVideoWrapper.class, Bitmap.class, imageVideoDataLoadProvider);
GifDrawableLoadProvider gifDrawableLoadProvider =
- new GifDrawableLoadProvider(context, bitmapPool, decodeFormat);
+ new GifDrawableLoadProvider(context, bitmapPool);
dataLoadProviderRegistry.register(InputStream.class, GifDrawable.class, gifDrawableLoadProvider);
dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
@@ -333,12 +335,12 @@ public class Glide {
* pre-filling only happens when the Activity is first created, rather than on every rotation.
* </p>
*
- * @param bitmapAttributes The list of {@link com.bumptech.glide.load.engine.prefill.PreFillBitmapAttribute}s
- * representing individual sizes and configurations of {@link android.graphics.Bitmap}s to
- * be pre-filled.
+ * @param bitmapAttributeBuilders The list of
+ * {@link com.bumptech.glide.load.engine.prefill.PreFillType.Builder Builders} representing
+ * individual sizes and configurations of {@link android.graphics.Bitmap}s to be pre-filled.
*/
- public void preFillBitmapPool(PreFillBitmapAttribute... bitmapAttributes) {
- bitmapPreFiller.preFill(bitmapAttributes);
+ public void preFillBitmapPool(PreFillType.Builder... bitmapAttributeBuilders) {
+ bitmapPreFiller.preFill(bitmapAttributeBuilders);
}
/**
@@ -492,7 +494,7 @@ public class Glide {
}
return null;
}
- return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass, context);
+ return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
}
/**
diff --git a/library/src/main/java/com/bumptech/glide/GlideBuilder.java b/library/src/main/java/com/bumptech/glide/GlideBuilder.java
index f7ffcecb..49e4d2fe 100644
--- a/library/src/main/java/com/bumptech/glide/GlideBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/GlideBuilder.java
@@ -2,6 +2,7 @@ package com.bumptech.glide;
import android.content.Context;
import android.os.Build;
+
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
diff --git a/library/src/main/java/com/bumptech/glide/RequestManager.java b/library/src/main/java/com/bumptech/glide/RequestManager.java
index 17a3f280..071a91e7 100644
--- a/library/src/main/java/com/bumptech/glide/RequestManager.java
+++ b/library/src/main/java/com/bumptech/glide/RequestManager.java
@@ -5,10 +5,9 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
-import com.bumptech.glide.signature.ApplicationVersionSignature;
-import com.bumptech.glide.signature.MediaStoreSignature;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.file_descriptor.FileDescriptorModelLoader;
import com.bumptech.glide.load.model.stream.MediaStoreStreamLoader;
@@ -19,6 +18,8 @@ import com.bumptech.glide.manager.ConnectivityMonitorFactory;
import com.bumptech.glide.manager.Lifecycle;
import com.bumptech.glide.manager.LifecycleListener;
import com.bumptech.glide.manager.RequestTracker;
+import com.bumptech.glide.signature.ApplicationVersionSignature;
+import com.bumptech.glide.signature.MediaStoreSignature;
import com.bumptech.glide.signature.StringSignature;
import com.bumptech.glide.util.Util;
@@ -52,7 +53,7 @@ public class RequestManager implements LifecycleListener {
RequestManager(Context context, final Lifecycle lifecycle, RequestTracker requestTracker,
ConnectivityMonitorFactory factory) {
- this.context = context;
+ this.context = context.getApplicationContext();
this.lifecycle = lifecycle;
this.requestTracker = requestTracker;
this.glide = Glide.get(context);
@@ -297,6 +298,10 @@ public class RequestManager implements LifecycleListener {
* @see com.bumptech.glide.GenericRequestBuilder#signature(com.bumptech.glide.load.Key)
* @see com.bumptech.glide.signature.MediaStoreSignature
*
+ * @deprecated Use {@link #loadFromMediaStore(android.net.Uri)},
+ * {@link com.bumptech.glide.signature.MediaStoreSignature}, and
+ * {@link com.bumptech.glide.DrawableRequestBuilder#signature(com.bumptech.glide.load.Key)} instead. Scheduled to be
+ * removed in Glide 4.0.
* @param uri The uri representing the media.
* @param mimeType The mime type of the media store media. Ok to default to empty string "". See
* {@link android.provider.MediaStore.Images.ImageColumns#MIME_TYPE} or
@@ -307,6 +312,7 @@ public class RequestManager implements LifecycleListener {
* @param orientation The orientation of the media store media. Ok to default to 0. See
* {@link android.provider.MediaStore.Images.ImageColumns#ORIENTATION}.
*/
+ @Deprecated
public DrawableTypeRequest<Uri> loadFromMediaStore(Uri uri, String mimeType, long dateModified, int orientation) {
Key signature = new MediaStoreSignature(mimeType, dateModified, orientation);
return (DrawableTypeRequest<Uri>) loadFromMediaStore(uri).signature(signature);
@@ -481,7 +487,8 @@ public class RequestManager implements LifecycleListener {
* @see #load(byte[])
*
* @deprecated Use {@link #load(byte[])} along with
- * {@link com.bumptech.glide.GenericRequestBuilder#signature(com.bumptech.glide.load.Key)} instead.
+ * {@link com.bumptech.glide.GenericRequestBuilder#signature(com.bumptech.glide.load.Key)} instead. Scheduled to be
+ * removed in Glide 4.0.
* @param model The data to load.
* @param id A unique id that identifies the image represented by the model suitable for use as a cache key
* (url, filepath etc). If there is no suitable id, use {@link #load(byte[])} instead.
diff --git a/library/src/main/java/com/bumptech/glide/load/ResourceDecoder.java b/library/src/main/java/com/bumptech/glide/load/ResourceDecoder.java
index 4f686e1b..3de450f6 100644
--- a/library/src/main/java/com/bumptech/glide/load/ResourceDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/ResourceDecoder.java
@@ -26,8 +26,8 @@ public interface ResourceDecoder<T, Z> {
* </p>
*
* @param source The data the resource should be decoded from.
- * @param width The ideal width of the decoded resource.
- * @param height The ideal height of the decoded resource.
+ * @param width The ideal width in pixels of the decoded resource.
+ * @param height The ideal height in pixels of the decoded resource.
* @throws IOException
*/
Resource<Z> decode(T source, int width, int height) throws IOException;
diff --git a/library/src/main/java/com/bumptech/glide/load/data/AssetPathFetcher.java b/library/src/main/java/com/bumptech/glide/load/data/AssetPathFetcher.java
index 7bac767e..7c9e6229 100644
--- a/library/src/main/java/com/bumptech/glide/load/data/AssetPathFetcher.java
+++ b/library/src/main/java/com/bumptech/glide/load/data/AssetPathFetcher.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.data;
import android.content.res.AssetManager;
import android.util.Log;
+
import com.bumptech.glide.Priority;
import java.io.IOException;
diff --git a/library/src/main/java/com/bumptech/glide/load/data/HttpUrlFetcher.java b/library/src/main/java/com/bumptech/glide/load/data/HttpUrlFetcher.java
index a2175603..7662eb2c 100644
--- a/library/src/main/java/com/bumptech/glide/load/data/HttpUrlFetcher.java
+++ b/library/src/main/java/com/bumptech/glide/load/data/HttpUrlFetcher.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.data;
import android.text.TextUtils;
+
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.model.GlideUrl;
diff --git a/library/src/main/java/com/bumptech/glide/load/data/LocalUriFetcher.java b/library/src/main/java/com/bumptech/glide/load/data/LocalUriFetcher.java
index 6a9d046a..8c3a999a 100644
--- a/library/src/main/java/com/bumptech/glide/load/data/LocalUriFetcher.java
+++ b/library/src/main/java/com/bumptech/glide/load/data/LocalUriFetcher.java
@@ -4,6 +4,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
+
import com.bumptech.glide.Priority;
import java.io.FileNotFoundException;
diff --git a/library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java b/library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java
index af47dd2f..b9b622a1 100644
--- a/library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java
+++ b/library/src/main/java/com/bumptech/glide/load/data/MediaStoreThumbFetcher.java
@@ -6,6 +6,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;
+
import com.bumptech.glide.Priority;
import java.io.File;
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/DecodeJob.java b/library/src/main/java/com/bumptech/glide/load/engine/DecodeJob.java
index 024dfa1c..f3d9c008 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/DecodeJob.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/DecodeJob.java
@@ -1,7 +1,7 @@
package com.bumptech.glide.load.engine;
-import android.os.SystemClock;
import android.util.Log;
+
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Key;
@@ -10,6 +10,7 @@ import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.engine.cache.DiskCache;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import com.bumptech.glide.provider.DataLoadProvider;
+import com.bumptech.glide.util.LogTime;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -28,6 +29,7 @@ import java.io.OutputStream;
*/
class DecodeJob<A, T, Z> {
private static final String TAG = "DecodeJob";
+ private static final FileOpener DEFAULT_FILE_OPENER = new FileOpener();
private final EngineKey resultKey;
private final int width;
@@ -39,11 +41,21 @@ class DecodeJob<A, T, Z> {
private final DiskCacheStrategy diskCacheStrategy;
private final DiskCache diskCache;
private final Priority priority;
+ private final FileOpener fileOpener;
+
private volatile boolean isCancelled;
public DecodeJob(EngineKey resultKey, int width, int height, DataFetcher<A> fetcher,
DataLoadProvider<A, T> loadProvider, Transformation<T> transformation, ResourceTranscoder<T, Z> transcoder,
DiskCache diskCache, DiskCacheStrategy diskCacheStrategy, Priority priority) {
+ this(resultKey, width, height, fetcher, loadProvider, transformation, transcoder, diskCache, diskCacheStrategy,
+ priority, DEFAULT_FILE_OPENER);
+ }
+
+ // Visible for testing.
+ DecodeJob(EngineKey resultKey, int width, int height, DataFetcher<A> fetcher,
+ DataLoadProvider<A, T> loadProvider, Transformation<T> transformation, ResourceTranscoder<T, Z> transcoder,
+ DiskCache diskCache, DiskCacheStrategy diskCacheStrategy, Priority priority, FileOpener fileOpener) {
this.resultKey = resultKey;
this.width = width;
this.height = height;
@@ -54,6 +66,7 @@ class DecodeJob<A, T, Z> {
this.diskCacheStrategy = diskCacheStrategy;
this.diskCache = diskCache;
this.priority = priority;
+ this.fileOpener = fileOpener;
}
/**
@@ -67,8 +80,17 @@ class DecodeJob<A, T, Z> {
return null;
}
+ long startTime = LogTime.getLogTime();
Resource<T> transformed = loadFromCache(resultKey);
- return transcode(transformed);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Decoded transformed from cache", startTime);
+ }
+ startTime = LogTime.getLogTime();
+ Resource<Z> result = transcode(transformed);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Transcoded transformed from cache", startTime);
+ }
+ return result;
}
/**
@@ -82,7 +104,11 @@ class DecodeJob<A, T, Z> {
return null;
}
+ long startTime = LogTime.getLogTime();
Resource<T> decoded = loadFromCache(resultKey.getOriginalKey());
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Decoded source from cache", startTime);
+ }
return transformEncodeAndTranscode(decoded);
}
@@ -108,23 +134,42 @@ class DecodeJob<A, T, Z> {
}
private Resource<Z> transformEncodeAndTranscode(Resource<T> decoded) {
+ long startTime = LogTime.getLogTime();
Resource<T> transformed = transform(decoded);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Transformed resource from source", startTime);
+ }
+
writeTransformedToCache(transformed);
- return transcode(transformed);
+
+ startTime = LogTime.getLogTime();
+ Resource<Z> result = transcode(transformed);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Transcoded transformed from source", startTime);
+ }
+ return result;
}
private void writeTransformedToCache(Resource<T> transformed) {
if (transformed == null || !diskCacheStrategy.cacheResult()) {
return;
}
+ long startTime = LogTime.getLogTime();
SourceWriter<Resource<T>> writer = new SourceWriter<Resource<T>>(loadProvider.getEncoder(), transformed);
diskCache.put(resultKey, writer);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Wrote transformed from source to cache", startTime);
+ }
}
private Resource<T> decodeSource() throws Exception {
Resource<T> decoded = null;
try {
+ long startTime = LogTime.getLogTime();
final A data = fetcher.loadData(priority);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Fetched data", startTime);
+ }
if (isCancelled) {
return null;
}
@@ -140,15 +185,29 @@ class DecodeJob<A, T, Z> {
if (diskCacheStrategy.cacheSource()) {
decoded = cacheAndDecodeSourceData(data);
} else {
+ long startTime = LogTime.getLogTime();
decoded = loadProvider.getSourceDecoder().decode(data, width, height);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Decoded from source", startTime);
+ }
}
return decoded;
}
private Resource<T> cacheAndDecodeSourceData(A data) throws IOException {
+ long startTime = LogTime.getLogTime();
SourceWriter<A> writer = new SourceWriter<A>(loadProvider.getSourceEncoder(), data);
diskCache.put(resultKey.getOriginalKey(), writer);
- return loadFromCache(resultKey.getOriginalKey());
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ logWithTimeAndKey("Wrote source to cache", startTime);
+ }
+
+ startTime = LogTime.getLogTime();
+ Resource<T> result = loadFromCache(resultKey.getOriginalKey());
+ if (Log.isLoggable(TAG, Log.VERBOSE) && result != null) {
+ logWithTimeAndKey("Decoded source from cache", startTime);
+ }
+ return result;
}
private Resource<T> loadFromCache(Key key) throws IOException {
@@ -187,23 +246,26 @@ class DecodeJob<A, T, Z> {
return transcoder.transcode(transformed);
}
- static class SourceWriter<T> implements DiskCache.Writer {
+ private void logWithTimeAndKey(String message, long startTime) {
+ Log.v(TAG, message + " in " + LogTime.getElapsedMillis(startTime) + resultKey);
+ }
+
+ class SourceWriter<DataType> implements DiskCache.Writer {
- private final Encoder<T> encoder;
- private final T data;
+ private final Encoder<DataType> encoder;
+ private final DataType data;
- public SourceWriter(Encoder<T> encoder, T data) {
+ public SourceWriter(Encoder<DataType> encoder, DataType data) {
this.encoder = encoder;
this.data = data;
}
@Override
public boolean write(File file) {
- long start = SystemClock.currentThreadTimeMillis();
boolean success = false;
OutputStream os = null;
try {
- os = new BufferedOutputStream(new FileOutputStream(file));
+ os = fileOpener.open(file);
success = encoder.encode(data, os);
} catch (FileNotFoundException e) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
@@ -218,10 +280,13 @@ class DecodeJob<A, T, Z> {
}
}
}
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "wrote to disk cache in " + (SystemClock.currentThreadTimeMillis() - start));
- }
return success;
}
}
+
+ static class FileOpener {
+ public OutputStream open(File file) throws FileNotFoundException {
+ return new BufferedOutputStream(new FileOutputStream(file));
+ }
+ }
}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/Engine.java b/library/src/main/java/com/bumptech/glide/load/engine/Engine.java
index c8c028e2..1e7a9e7f 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/Engine.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/Engine.java
@@ -1,10 +1,9 @@
package com.bumptech.glide.load.engine;
-import android.os.Handler;
import android.os.Looper;
-import android.os.Message;
import android.os.MessageQueue;
import android.util.Log;
+
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.Transformation;
@@ -35,7 +34,7 @@ public class Engine implements EngineJobListener, MemoryCache.ResourceRemovedLis
private final EngineJobFactory engineJobFactory;
private final Map<Key, WeakReference<EngineResource<?>>> activeResources;
private final ReferenceQueue<EngineResource<?>> resourceReferenceQueue;
- private final Handler mainHandler;
+ private final ResourceRecycler resourceRecycler;
/**
* Allows a request to indicate it no longer is interested in a given load.
@@ -56,13 +55,14 @@ public class Engine implements EngineJobListener, MemoryCache.ResourceRemovedLis
public Engine(MemoryCache memoryCache, DiskCache diskCache, ExecutorService diskCacheService,
ExecutorService sourceService) {
- this(memoryCache, diskCache, diskCacheService, sourceService, null, null, null, null);
+ this(memoryCache, diskCache, diskCacheService, sourceService, null, null, null, null, null);
}
// Visible for testing.
Engine(MemoryCache cache, DiskCache diskCache, ExecutorService diskCacheService, ExecutorService sourceService,
Map<Key, EngineJob> jobs, EngineKeyFactory keyFactory,
- Map<Key, WeakReference<EngineResource<?>>> activeResources, EngineJobFactory engineJobFactory) {
+ Map<Key, WeakReference<EngineResource<?>>> activeResources, EngineJobFactory engineJobFactory,
+ ResourceRecycler resourceRecycler) {
this.cache = cache;
this.diskCache = diskCache;
@@ -86,12 +86,15 @@ public class Engine implements EngineJobListener, MemoryCache.ResourceRemovedLis
}
this.engineJobFactory = engineJobFactory;
+ if (resourceRecycler == null) {
+ resourceRecycler = new ResourceRecycler();
+ }
+ this.resourceRecycler = resourceRecycler;
+
resourceReferenceQueue = new ReferenceQueue<EngineResource<?>>();
MessageQueue queue = Looper.myQueue();
queue.addIdleHandler(new RefQueueIdleHandler(activeResources, resourceReferenceQueue));
cache.setResourceRemovedListener(this);
-
- mainHandler = new Handler(Looper.getMainLooper(), new ResourceRecyclerCallback());
}
/**
@@ -118,8 +121,8 @@ public class Engine implements EngineJobListener, MemoryCache.ResourceRemovedLis
*
* @param signature A non-null unique key to be mixed into the cache key that identifies the version of the data to
* be loaded.
- * @param width The target width of the retrieved resource.
- * @param height The target height of the retrieved resource.
+ * @param width The target width in pixels of the desired resource.
+ * @param height The target height in pixels of the desired resource.
* @param fetcher The fetcher to use to retrieve data not in the disk cache.
* @param loadProvider The load provider containing various encoders and decoders use to decode and encode data.
* @param transformation The transformation to use to transform the decoded resource.
@@ -244,7 +247,7 @@ public class Engine implements EngineJobListener, MemoryCache.ResourceRemovedLis
@Override
public void onResourceRemoved(final Resource<?> resource) {
- recycleResource(resource);
+ resourceRecycler.recycle(resource);
}
@Override
@@ -253,27 +256,7 @@ public class Engine implements EngineJobListener, MemoryCache.ResourceRemovedLis
if (resource.isCacheable()) {
cache.put(cacheKey, resource);
} else {
- recycleResource(resource);
- }
- }
-
- private void recycleResource(Resource<?> resource) {
- // If a resource has sub-resources, releasing a sub resource can cause it's parent to be synchronously
- // evicted which leads to a recycle loop when the parent the releases it's children. Posting breaks this loops.
- mainHandler.obtainMessage(ResourceRecyclerCallback.RECYCLE_RESOURCE, resource).sendToTarget();
- }
-
- private static class ResourceRecyclerCallback implements Handler.Callback {
- public static final int RECYCLE_RESOURCE = 1;
-
- @Override
- public boolean handleMessage(Message message) {
- if (message.what == RECYCLE_RESOURCE) {
- Resource resource = (Resource) message.obj;
- resource.recycle();
- return true;
- }
- return false;
+ resourceRecycler.recycle(resource);
}
}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/EngineJob.java b/library/src/main/java/com/bumptech/glide/load/engine/EngineJob.java
index ef9ffcac..06926317 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/EngineJob.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/EngineJob.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.engine;
import android.os.Handler;
import android.os.Message;
+
import com.bumptech.glide.load.Key;
import com.bumptech.glide.request.ResourceCallback;
import com.bumptech.glide.util.Util;
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/EngineResource.java b/library/src/main/java/com/bumptech/glide/load/engine/EngineResource.java
index 92574e1f..49bf096a 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/EngineResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/EngineResource.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.engine;
import android.os.Looper;
+
import com.bumptech.glide.load.Key;
/**
@@ -22,6 +23,9 @@ class EngineResource<Z> implements Resource<Z> {
}
EngineResource(Resource<Z> toWrap, boolean isCacheable) {
+ if (toWrap == null) {
+ throw new NullPointerException("Wrapped resource must not be null");
+ }
resource = toWrap;
this.isCacheable = isCacheable;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/EngineRunnable.java b/library/src/main/java/com/bumptech/glide/load/engine/EngineRunnable.java
index 949f5978..98ec65ec 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/EngineRunnable.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/EngineRunnable.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.engine;
import android.util.Log;
+
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.engine.executor.Prioritized;
import com.bumptech.glide.request.ResourceCallback;
@@ -63,6 +64,9 @@ class EngineRunnable implements Runnable, Prioritized {
}
if (isCancelled) {
+ if (resource != null) {
+ resource.recycle();
+ }
return;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/ResourceRecycler.java b/library/src/main/java/com/bumptech/glide/load/engine/ResourceRecycler.java
new file mode 100644
index 00000000..c30376cf
--- /dev/null
+++ b/library/src/main/java/com/bumptech/glide/load/engine/ResourceRecycler.java
@@ -0,0 +1,42 @@
+package com.bumptech.glide.load.engine;
+
+import android.os.Handler;
+import android.os.Message;
+
+import com.bumptech.glide.util.Util;
+
+/**
+ * A class that can safely recycle recursive resources.
+ */
+class ResourceRecycler {
+ private boolean isRecycling;
+ private final Handler handler = new Handler(new ResourceRecyclerCallback());
+
+ public void recycle(Resource<?> resource) {
+ Util.assertMainThread();
+
+ if (isRecycling) {
+ // If a resource has sub-resources, releasing a sub resource can cause it's parent to be synchronously
+ // evicted which leads to a recycle loop when the parent releases it's children. Posting breaks this loop.
+ handler.obtainMessage(ResourceRecyclerCallback.RECYCLE_RESOURCE, resource).sendToTarget();
+ } else {
+ isRecycling = true;
+ resource.recycle();
+ isRecycling = false;
+ }
+ }
+
+ private static class ResourceRecyclerCallback implements Handler.Callback {
+ public static final int RECYCLE_RESOURCE = 1;
+
+ @Override
+ public boolean handleMessage(Message message) {
+ if (message.what == RECYCLE_RESOURCE) {
+ Resource resource = (Resource) message.obj;
+ resource.recycle();
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/AttributeStrategy.java b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/AttributeStrategy.java
index ef57437e..eebd1fd5 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/AttributeStrategy.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/AttributeStrategy.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.engine.bitmap_recycle;
import android.graphics.Bitmap;
+
import com.bumptech.glide.util.Util;
/**
@@ -56,7 +57,8 @@ class AttributeStrategy implements LruPoolStrategy {
return "[" + width + "x" + height + "], " + config;
}
- private static class KeyPool extends BaseKeyPool<Key> {
+ // Visible for testing.
+ static class KeyPool extends BaseKeyPool<Key> {
public Key get(int width, int height, Bitmap.Config config) {
Key result = get();
result.init(width, height, config);
@@ -69,7 +71,8 @@ class AttributeStrategy implements LruPoolStrategy {
}
}
- private static class Key implements Poolable {
+ // Visible for testing.
+ static class Key implements Poolable {
private final KeyPool pool;
private int width;
private int height;
@@ -88,26 +91,13 @@ class AttributeStrategy implements LruPoolStrategy {
@Override
public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- Key key = (Key) o;
-
- if (height != key.height) {
- return false;
- }
- if (width != key.width) {
- return false;
+ if (o instanceof Key) {
+ Key other = (Key) o;
+ return width == other.width
+ && height == other.height
+ && config == other.config;
}
- if (config != key.config) {
- return false;
- }
-
- return true;
+ return false;
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPool.java b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPool.java
index 3dd4c38d..0390a668 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPool.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPool.java
@@ -71,8 +71,8 @@ public interface BitmapPool {
*
* @see #getDirty(int, int, android.graphics.Bitmap.Config)
*
- * @param width The width of the desired {@link android.graphics.Bitmap}.
- * @param height The height of the desired {@link android.graphics.Bitmap}.
+ * @param width The width in pixels of the desired {@link android.graphics.Bitmap}.
+ * @param height The height in pixels of the desired {@link android.graphics.Bitmap}.
* @param config The {@link android.graphics.Bitmap.Config} of the desired {@link android.graphics.Bitmap}.
*/
Bitmap get(int width, int height, Bitmap.Config config);
@@ -89,8 +89,8 @@ public interface BitmapPool {
*
* @see #get(int, int, android.graphics.Bitmap.Config)
*
- * @param width The width of the desired {@link android.graphics.Bitmap}.
- * @param height The height of the desired {@link android.graphics.Bitmap}.
+ * @param width The width in pixels of the desired {@link android.graphics.Bitmap}.
+ * @param height The height in pixels of the desired {@link android.graphics.Bitmap}.
* @param config The {@link android.graphics.Bitmap.Config} of the desired {@link android.graphics.Bitmap}.
* @return A {@link android.graphics.Bitmap} with exactly the given width, height, and config potentially containing
* random image data or null if no such {@link android.graphics.Bitmap} could be obtained from the pool.
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/LruBitmapPool.java b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/LruBitmapPool.java
index cc59abc1..79d8c6c4 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/LruBitmapPool.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/LruBitmapPool.java
@@ -63,6 +63,10 @@ public class LruBitmapPool implements BitmapPool {
@Override
public synchronized boolean put(Bitmap bitmap) {
if (!bitmap.isMutable() || strategy.getSize(bitmap) > maxSize) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Reject bitmap from pool=" + strategy.logBitmap(bitmap) + " is mutable="
+ + bitmap.isMutable());
+ }
return false;
}
@@ -73,8 +77,8 @@ public class LruBitmapPool implements BitmapPool {
puts++;
currentSize += size;
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Put bitmap in pool=" + strategy.logBitmap(bitmap));
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Put bitmap in pool=" + strategy.logBitmap(bitmap));
}
dump();
@@ -118,8 +122,8 @@ public class LruBitmapPool implements BitmapPool {
result.setHasAlpha(true);
}
}
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Get bitmap=" + strategy.logBitmap(width, height, config));
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Get bitmap=" + strategy.logBitmap(width, height, config));
}
dump();
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/SizeStrategy.java b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/SizeStrategy.java
index b33d13ac..2716d337 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/SizeStrategy.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/SizeStrategy.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.load.engine.bitmap_recycle;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.os.Build;
+
import com.bumptech.glide.util.Util;
import java.util.TreeMap;
@@ -119,7 +120,8 @@ class SizeStrategy implements LruPoolStrategy {
return "[" + size + "]";
}
- private static class KeyPool extends BaseKeyPool<Key> {
+ // Visible for testing.
+ static class KeyPool extends BaseKeyPool<Key> {
public Key get(int size) {
Key result = get();
@@ -133,7 +135,8 @@ class SizeStrategy implements LruPoolStrategy {
}
}
- private static final class Key implements Poolable {
+ // Visible for testing.
+ static final class Key implements Poolable {
private final KeyPool pool;
private int size;
@@ -147,16 +150,11 @@ class SizeStrategy implements LruPoolStrategy {
@Override
public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
+ if (o instanceof Key) {
+ Key other = (Key) o;
+ return size == other.size;
}
-
- Key key = (Key) o;
-
- return size == key.size;
+ return false;
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/cache/LruResourceCache.java b/library/src/main/java/com/bumptech/glide/load/engine/cache/LruResourceCache.java
index 3cb8b5c2..ffe5a6f9 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/cache/LruResourceCache.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/cache/LruResourceCache.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.engine.cache;
import android.annotation.SuppressLint;
+
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.util.LruCache;
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/executor/FifoPriorityThreadPoolExecutor.java b/library/src/main/java/com/bumptech/glide/load/engine/executor/FifoPriorityThreadPoolExecutor.java
index 9972fc6d..db0a128a 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/executor/FifoPriorityThreadPoolExecutor.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/executor/FifoPriorityThreadPoolExecutor.java
@@ -34,7 +34,7 @@ public class FifoPriorityThreadPoolExecutor extends ThreadPoolExecutor {
@Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
- return new FifoPriorityLoadTask<T>(runnable, value, ordering.getAndIncrement());
+ return new LoadTask<T>(runnable, value, ordering.getAndIncrement());
}
/**
@@ -57,11 +57,12 @@ public class FifoPriorityThreadPoolExecutor extends ThreadPoolExecutor {
}
}
- private static class FifoPriorityLoadTask<T> extends FutureTask<T> implements Comparable<FifoPriorityLoadTask<?>> {
+ // Visible for testing.
+ static class LoadTask<T> extends FutureTask<T> implements Comparable<LoadTask<?>> {
private final int priority;
private final int order;
- public FifoPriorityLoadTask(Runnable runnable, T result, int order) {
+ public LoadTask(Runnable runnable, T result, int order) {
super(runnable, result);
if (!(runnable instanceof Prioritized)) {
throw new IllegalArgumentException("FifoPriorityThreadPoolExecutor must be given Runnables that "
@@ -71,25 +72,14 @@ public class FifoPriorityThreadPoolExecutor extends ThreadPoolExecutor {
this.order = order;
}
+ @SuppressWarnings("unchecked")
@Override
public boolean equals(Object o) {
- if (this == o) {
- return true;
+ if (o instanceof LoadTask) {
+ LoadTask<Object> other = (LoadTask<Object>) o;
+ return order == other.order && priority == other.priority;
}
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- FifoPriorityLoadTask that = (FifoPriorityLoadTask) o;
-
- if (order != that.order) {
- return false;
- }
- if (priority != that.priority) {
- return false;
- }
-
- return true;
+ return false;
}
@Override
@@ -100,7 +90,7 @@ public class FifoPriorityThreadPoolExecutor extends ThreadPoolExecutor {
}
@Override
- public int compareTo(FifoPriorityLoadTask<?> loadTask) {
+ public int compareTo(LoadTask<?> loadTask) {
int result = priority - loadTask.priority;
if (result == 0) {
result = order - loadTask.order;
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillIdleHandler.java b/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillIdleHandler.java
deleted file mode 100644
index 05be13b9..00000000
--- a/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillIdleHandler.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.bumptech.glide.load.engine.prefill;
-
-import android.graphics.Bitmap;
-import android.os.MessageQueue;
-import android.os.SystemClock;
-import android.util.Log;
-import com.bumptech.glide.load.Key;
-import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
-import com.bumptech.glide.load.engine.cache.MemoryCache;
-import com.bumptech.glide.load.resource.bitmap.BitmapResource;
-import com.bumptech.glide.util.Util;
-
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-
-/**
- * A class that allocates {@link android.graphics.Bitmap Bitmaps} when the main thread runs out of messages so that the
- * {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} is pre-populated.
- */
-final class BitmapPreFillIdleHandler implements MessageQueue.IdleHandler {
- private static final String TAG = "PreFillIdleHandler";
- // Visisble for testing.
- static final long MAX_DURATION_MILLIS = 32;
-
- private static final Clock DEFAULT_CLOCK = new Clock();
-
- private final BitmapPool bitmapPool;
- private final MemoryCache memoryCache;
- private final PreFillQueue toPrefill;
- private final Clock clock;
-
- private boolean isCancelled;
-
- public BitmapPreFillIdleHandler(BitmapPool bitmapPool, MemoryCache memoryCache,
- PreFillQueue allocationOrder) {
- this(bitmapPool, memoryCache, allocationOrder, DEFAULT_CLOCK);
- }
-
- // Visible for testing.
- BitmapPreFillIdleHandler(BitmapPool bitmapPool, MemoryCache memoryCache,
- PreFillQueue allocationOrder, Clock clock) {
- this.bitmapPool = bitmapPool;
- this.memoryCache = memoryCache;
- this.toPrefill = allocationOrder;
- this.clock = clock;
- }
-
- public void cancel() {
- isCancelled = true;
- }
-
- @Override
- public boolean queueIdle() {
- long start = clock.now();
- while (!toPrefill.isEmpty() && (clock.now() - start) < MAX_DURATION_MILLIS) {
- PreFillBitmapAttribute toAllocate = toPrefill.remove();
- Bitmap bitmap = Bitmap.createBitmap(toAllocate.getWidth(), toAllocate.getHeight(),
- toAllocate.getConfig());
-
- // Don't over fill the memory cache to avoid evicting useful resources, but make sure it's not empty so
- // we use all available space.
- if ((memoryCache.getMaxSize() - memoryCache.getCurrentSize()) >= Util.getBitmapByteSize(bitmap)) {
- memoryCache.put(new UniqueKey(), new BitmapResource(bitmap, bitmapPool));
- } else {
- bitmapPool.put(bitmap);
- }
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "allocated [" + toAllocate.getWidth() + "x" + toAllocate.getHeight() + "] "
- + toAllocate.getConfig() + " size: " + Util.getBitmapByteSize(bitmap));
- }
- }
-
- return !isCancelled && !toPrefill.isEmpty();
- }
-
- private static class UniqueKey implements Key {
-
- @Override
- public void updateDiskCacheKey(MessageDigest messageDigest) throws UnsupportedEncodingException {
- // Do nothing.
- }
- }
-
- // Visible for testing.
- static class Clock {
- public long now() {
- return SystemClock.currentThreadTimeMillis();
- }
- }
-}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillRunner.java b/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillRunner.java
new file mode 100644
index 00000000..6af89c19
--- /dev/null
+++ b/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFillRunner.java
@@ -0,0 +1,161 @@
+package com.bumptech.glide.load.engine.prefill;
+
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.bumptech.glide.load.Key;
+import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
+import com.bumptech.glide.load.engine.cache.MemoryCache;
+import com.bumptech.glide.load.resource.bitmap.BitmapResource;
+import com.bumptech.glide.util.Util;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A class that allocates {@link android.graphics.Bitmap Bitmaps} to make sure that the
+ * {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} is pre-populated.
+ *
+ * <p>By posting to the main thread with backoffs, we try to avoid ANRs when the garbage collector gets into a state
+ * where a high percentage of {@link Bitmap} allocations trigger a stop the world GC. We try to detect whether or not a
+ * GC has occurred by only allowing our allocator to run for a limited number of milliseconds. Since the allocations
+ * themselves very fast, a GC is the most likely reason for a substantial delay. If we detect our allocator has run for
+ * more than our limit, we assume a GC has occurred, stop the current allocations, and try again after a delay.
+ */
+final class BitmapPreFillRunner implements Runnable {
+ private static final String TAG = "PreFillRunner";
+ private static final Clock DEFAULT_CLOCK = new Clock();
+
+ /**
+ * The maximum number of millis we can run before posting. Set to match and detect the duration of non concurrent
+ * GCs.
+ */
+ static final long MAX_DURATION_MS = 32;
+
+ /**
+ * The amount of time in ms we wait before continuing to allocate after the first GC is detected.
+ */
+ static final long INITIAL_BACKOFF_MS = 40;
+
+ /**
+ * The amount by which the current backoff time is multiplied each time we detect a GC.
+ */
+ static final int BACKOFF_RATIO = 4;
+
+ /**
+ * The maximum amount of time in ms we wait before continuing to allocate.
+ */
+ static final long MAX_BACKOFF_MS = TimeUnit.SECONDS.toMillis(1);
+
+ private final BitmapPool bitmapPool;
+ private final MemoryCache memoryCache;
+ private final PreFillQueue toPrefill;
+ private final Clock clock;
+ private final Set<PreFillType> seenTypes = new HashSet<PreFillType>();
+ private final Handler handler;
+
+ private long currentDelay = INITIAL_BACKOFF_MS;
+ private boolean isCancelled;
+
+ public BitmapPreFillRunner(BitmapPool bitmapPool, MemoryCache memoryCache, PreFillQueue allocationOrder) {
+ this(bitmapPool, memoryCache, allocationOrder, DEFAULT_CLOCK, new Handler(Looper.getMainLooper()));
+ }
+
+ // Visible for testing.
+ BitmapPreFillRunner(BitmapPool bitmapPool, MemoryCache memoryCache, PreFillQueue allocationOrder, Clock clock,
+ Handler handler) {
+ this.bitmapPool = bitmapPool;
+ this.memoryCache = memoryCache;
+ this.toPrefill = allocationOrder;
+ this.clock = clock;
+ this.handler = handler;
+ }
+
+ public void cancel() {
+ isCancelled = true;
+ }
+
+ /**
+ * Attempts to allocate {@link android.graphics.Bitmap}s and returns {@code true} if there are more
+ * {@link android.graphics.Bitmap}s to allocate and {@code false} otherwise.
+ */
+ private boolean allocate() {
+ long start = clock.now();
+ while (!toPrefill.isEmpty() && !isGcDetected(start)) {
+ PreFillType toAllocate = toPrefill.remove();
+ Bitmap bitmap = Bitmap.createBitmap(toAllocate.getWidth(), toAllocate.getHeight(),
+ toAllocate.getConfig());
+
+ // Don't over fill the memory cache to avoid evicting useful resources, but make sure it's not empty so
+ // we use all available space.
+ if (getFreeMemoryCacheBytes() >= Util.getBitmapByteSize(bitmap)) {
+ memoryCache.put(new UniqueKey(), BitmapResource.obtain(bitmap, bitmapPool));
+ } else {
+ addToBitmapPool(toAllocate, bitmap);
+ }
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "allocated [" + toAllocate.getWidth() + "x" + toAllocate.getHeight() + "] "
+ + toAllocate.getConfig() + " size: " + Util.getBitmapByteSize(bitmap));
+ }
+ }
+
+ return !isCancelled && !toPrefill.isEmpty();
+ }
+
+ private boolean isGcDetected(long startTimeMs) {
+ return clock.now() - startTimeMs >= MAX_DURATION_MS;
+ }
+
+ private int getFreeMemoryCacheBytes() {
+ return memoryCache.getMaxSize() - memoryCache.getCurrentSize();
+ }
+
+ private void addToBitmapPool(PreFillType toAllocate, Bitmap bitmap) {
+ // The pool may not move sizes to the front of the LRU on put. Do a get here to make sure the size we're adding
+ // is at the front of the queue so that the Bitmap we're adding won't be evicted immediately.
+ if (seenTypes.add(toAllocate)) {
+ Bitmap fromPool = bitmapPool.get(toAllocate.getWidth(), toAllocate.getHeight(),
+ toAllocate.getConfig());
+ if (fromPool != null) {
+ bitmapPool.put(fromPool);
+ }
+ }
+
+ bitmapPool.put(bitmap);
+ }
+
+ @Override
+ public void run() {
+ if (allocate()) {
+ handler.postDelayed(this, getNextDelay());
+ }
+ }
+
+ private long getNextDelay() {
+ long result = currentDelay;
+ currentDelay = Math.min(currentDelay * BACKOFF_RATIO, MAX_BACKOFF_MS);
+ return result;
+ }
+
+ private static class UniqueKey implements Key {
+
+ @Override
+ public void updateDiskCacheKey(MessageDigest messageDigest) throws UnsupportedEncodingException {
+ // Do nothing.
+ }
+ }
+
+ // Visible for testing.
+ static class Clock {
+ public long now() {
+ return SystemClock.currentThreadTimeMillis();
+ }
+ }
+}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFiller.java b/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFiller.java
index b4d9f1c4..f2e9accc 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFiller.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFiller.java
@@ -1,6 +1,10 @@
package com.bumptech.glide.load.engine.prefill;
+import android.graphics.Bitmap;
+import android.os.Handler;
import android.os.Looper;
+
+import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.engine.cache.MemoryCache;
import com.bumptech.glide.util.Util;
@@ -16,36 +20,50 @@ public final class BitmapPreFiller {
private final MemoryCache memoryCache;
private final BitmapPool bitmapPool;
+ private final DecodeFormat defaultFormat;
+ private final Handler handler = new Handler(Looper.getMainLooper());
- private BitmapPreFillIdleHandler current;
+ private BitmapPreFillRunner current;
- public BitmapPreFiller(MemoryCache memoryCache, BitmapPool bitmapPool) {
+ public BitmapPreFiller(MemoryCache memoryCache, BitmapPool bitmapPool, DecodeFormat defaultFormat) {
this.memoryCache = memoryCache;
this.bitmapPool = bitmapPool;
+ this.defaultFormat = defaultFormat;
}
- public void preFill(PreFillBitmapAttribute... bitmapAttributes) {
+ public void preFill(PreFillType.Builder... bitmapAttributeBuilders) {
if (current != null) {
current.cancel();
}
+
+ PreFillType[] bitmapAttributes = new PreFillType[bitmapAttributeBuilders.length];
+ for (int i = 0; i < bitmapAttributeBuilders.length; i++) {
+ PreFillType.Builder builder = bitmapAttributeBuilders[i];
+ if (builder.getConfig() == null) {
+ builder.setConfig(defaultFormat == DecodeFormat.ALWAYS_ARGB_8888
+ ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
+ }
+ bitmapAttributes[i] = builder.build();
+ }
+
PreFillQueue allocationOrder = generateAllocationOrder(bitmapAttributes);
- current = new BitmapPreFillIdleHandler(bitmapPool, memoryCache, allocationOrder);
- Looper.myQueue().addIdleHandler(current);
+ current = new BitmapPreFillRunner(bitmapPool, memoryCache, allocationOrder);
+ handler.post(current);
}
// Visible for testing.
- PreFillQueue generateAllocationOrder(PreFillBitmapAttribute[] preFillSizes) {
+ PreFillQueue generateAllocationOrder(PreFillType[] preFillSizes) {
final int maxSize = memoryCache.getMaxSize() - memoryCache.getCurrentSize() + bitmapPool.getMaxSize();
int totalWeight = 0;
- for (PreFillBitmapAttribute size : preFillSizes) {
+ for (PreFillType size : preFillSizes) {
totalWeight += size.getWeight();
}
final float bytesPerWeight = maxSize / (float) totalWeight;
- Map<PreFillBitmapAttribute, Integer> attributeToCount = new HashMap<PreFillBitmapAttribute, Integer>();
- for (PreFillBitmapAttribute size : preFillSizes) {
+ Map<PreFillType, Integer> attributeToCount = new HashMap<PreFillType, Integer>();
+ for (PreFillType size : preFillSizes) {
int bytesForSize = Math.round(bytesPerWeight * size.getWeight());
int bytesPerBitmap = getSizeInBytes(size);
int bitmapsForSize = bytesForSize / bytesPerBitmap;
@@ -55,7 +73,7 @@ public final class BitmapPreFiller {
return new PreFillQueue(attributeToCount);
}
- private static int getSizeInBytes(PreFillBitmapAttribute size) {
+ private static int getSizeInBytes(PreFillType size) {
return Util.getBitmapByteSize(size.getWidth(), size.getHeight(), size.getConfig());
}
}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillBitmapAttribute.java b/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillBitmapAttribute.java
deleted file mode 100644
index b84763fa..00000000
--- a/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillBitmapAttribute.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.bumptech.glide.load.engine.prefill;
-
-import android.graphics.Bitmap;
-
-/**
- * A container for a set of options used to pre-fill a {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool}
- * with {@link Bitmap Bitmaps} of a single size and configuration.
- */
-public final class PreFillBitmapAttribute {
- // Visible for testing.
- static final Bitmap.Config DEFAULT_CONFIG = Bitmap.Config.RGB_565;
- private final int width;
- private final int height;
- private final Bitmap.Config config;
- private final int weight;
-
- /**
- * Constructor for a single type of {@link android.graphics.Bitmap}.
- *
- * @see #PreFillBitmapAttribute(int, int, int)
- * @see #PreFillBitmapAttribute(int, int, android.graphics.Bitmap.Config, int)
- *
- * @param width The width in pixels of the {@link android.graphics.Bitmap} to pre-fill.
- * @param height The height in pixels of the {@link android.graphics.Bitmap} to pre-fill.
- */
- public PreFillBitmapAttribute(int width, int height) {
- this(width, height, 1);
- }
-
- /**
- * Constructor for a single type of {@link android.graphics.Bitmap}.
- *
- * @see #PreFillBitmapAttribute(int, int)
- * @see #PreFillBitmapAttribute(int, int, android.graphics.Bitmap.Config, int)
- *
- * @param width The width in pixels of the {@link android.graphics.Bitmap} to pre-fill.
- * @param height The height in pixels of the {@link android.graphics.Bitmap} to pre-fill.
- * @param weight An integer indicating how to balance pre-filling this size and configuration of
- * {@link android.graphics.Bitmap} against any other sizes/configurations that may be being pre-filled.
- */
- public PreFillBitmapAttribute(int width, int height, int weight) {
- this(width, height, DEFAULT_CONFIG, weight);
- }
-
- /**
- * Constructor for a single type of {@link android.graphics.Bitmap}.
- *
- * @see #PreFillBitmapAttribute(int, int)
- * @see #PreFillBitmapAttribute(int, int, int)
- *
- * @param width The width in pixels of the {@link android.graphics.Bitmap Bitmaps} to
- * pre-fill.
- * @param height The height in pixels of the {@link android.graphics.Bitmap Bitmaps} to
- * pre-fill.
- * @param config The {@link android.graphics.Bitmap.Config} of the {@link android.graphics.Bitmap Bitmaps} to
- * pre-fill.
- * @param weight An integer indicating how to balance pre-filling this size and configuration of
- * {@link android.graphics.Bitmap} against any other sizes/configurations that may be being pre-filled.
- */
- public PreFillBitmapAttribute(int width, int height, Bitmap.Config config, int weight) {
- this.width = width;
- this.height = height;
- this.config = config;
- this.weight = weight;
- }
-
- /**
- * Returns the width in pixels of the {@link android.graphics.Bitmap Bitmaps}.
- */
- public int getWidth() {
- return width;
- }
-
- /**
- * Returns the height in pixels of the {@link android.graphics.Bitmap Bitmaps}.
- */
- public int getHeight() {
- return height;
- }
-
- /**
- * Returns the {@link android.graphics.Bitmap.Config} of the {@link android.graphics.Bitmap Bitmaps}.
- */
- public Bitmap.Config getConfig() {
- return config;
- }
-
- /**
- * Returns the weight of the {@link android.graphics.Bitmap Bitmaps} of this type.
- */
- public int getWeight() {
- return weight;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- } else if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- PreFillBitmapAttribute size = (PreFillBitmapAttribute) o;
-
- return height == size.height
- && weight == size.weight
- && width == size.width
- && config == size.config;
- }
-
- @Override
- public int hashCode() {
- int result = width;
- result = 31 * result + height;
- result = 31 * result + config.hashCode();
- result = 31 * result + weight;
- return result;
- }
-
- @Override
- public String toString() {
- return "PreFillSize{"
- + "width=" + width
- + ", height=" + height
- + ", config=" + config
- + ", weight=" + weight
- + '}';
- }
-}
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillQueue.java b/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillQueue.java
index abdc9e2b..f88032a8 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillQueue.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillQueue.java
@@ -6,23 +6,23 @@ import java.util.Map;
final class PreFillQueue {
- private final Map<PreFillBitmapAttribute, Integer> bitmapsPerType;
- private final List<PreFillBitmapAttribute> keyList;
+ private final Map<PreFillType, Integer> bitmapsPerType;
+ private final List<PreFillType> keyList;
private int bitmapsRemaining;
private int keyIndex;
- public PreFillQueue(Map<PreFillBitmapAttribute, Integer> bitmapsPerType) {
+ public PreFillQueue(Map<PreFillType, Integer> bitmapsPerType) {
this.bitmapsPerType = bitmapsPerType;
// We don't particularly care about the initial order.
- keyList = new ArrayList<PreFillBitmapAttribute>(bitmapsPerType.keySet());
+ keyList = new ArrayList<PreFillType>(bitmapsPerType.keySet());
for (Integer count : bitmapsPerType.values()) {
bitmapsRemaining += count;
}
}
- public PreFillBitmapAttribute remove() {
- PreFillBitmapAttribute result = keyList.get(keyIndex);
+ public PreFillType remove() {
+ PreFillType result = keyList.get(keyIndex);
Integer countForResult = bitmapsPerType.get(result);
if (countForResult == 1) {
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillType.java b/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillType.java
new file mode 100644
index 00000000..5037b352
--- /dev/null
+++ b/library/src/main/java/com/bumptech/glide/load/engine/prefill/PreFillType.java
@@ -0,0 +1,172 @@
+package com.bumptech.glide.load.engine.prefill;
+
+import android.graphics.Bitmap;
+
+/**
+ * A container for a set of options used to pre-fill a {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool}
+ * with {@link Bitmap Bitmaps} of a single size and configuration.
+ */
+public final class PreFillType {
+ // Visible for testing.
+ static final Bitmap.Config DEFAULT_CONFIG = Bitmap.Config.RGB_565;
+ private final int width;
+ private final int height;
+ private final Bitmap.Config config;
+ private final int weight;
+
+ /**
+ * Constructor for a single type of {@link android.graphics.Bitmap}.
+ *
+ * @param width The width in pixels of the {@link android.graphics.Bitmap Bitmaps} to
+ * pre-fill.
+ * @param height The height in pixels of the {@link android.graphics.Bitmap Bitmaps} to
+ * pre-fill.
+ * @param config The {@link android.graphics.Bitmap.Config} of the {@link android.graphics.Bitmap Bitmaps} to
+ * pre-fill.
+ * @param weight An integer indicating how to balance pre-filling this size and configuration of
+ * {@link android.graphics.Bitmap} against any other sizes/configurations that may be being pre-filled.
+ */
+ PreFillType(int width, int height, Bitmap.Config config, int weight) {
+ if (config == null) {
+ throw new NullPointerException("Config must not be null");
+ }
+
+ this.width = width;
+ this.height = height;
+ this.config = config;
+ this.weight = weight;
+ }
+
+ /**
+ * Returns the width in pixels of the {@link android.graphics.Bitmap Bitmaps}.
+ */
+ int getWidth() {
+ return width;
+ }
+
+ /**
+ * Returns the height in pixels of the {@link android.graphics.Bitmap Bitmaps}.
+ */
+ int getHeight() {
+ return height;
+ }
+
+ /**
+ * Returns the {@link android.graphics.Bitmap.Config} of the {@link android.graphics.Bitmap Bitmaps}.
+ */
+ Bitmap.Config getConfig() {
+ return config;
+ }
+
+ /**
+ * Returns the weight of the {@link android.graphics.Bitmap Bitmaps} of this type.
+ */
+ int getWeight() {
+ return weight;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof PreFillType) {
+ PreFillType other = (PreFillType) o;
+ return height == other.height
+ && width == other.width
+ && weight == other.weight
+ && config == other.config;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = width;
+ result = 31 * result + height;
+ result = 31 * result + config.hashCode();
+ result = 31 * result + weight;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "PreFillSize{"
+ + "width=" + width
+ + ", height=" + height
+ + ", config=" + config
+ + ", weight=" + weight
+ + '}';
+ }
+
+ /**
+ * Builder for {@link PreFillType}.
+ */
+ public static class Builder {
+ private final int width;
+ private final int height;
+
+ private Bitmap.Config config;
+ private int weight = 1;
+
+ /**
+ * Constructor for a builder that uses the given size as the width and height of the Bitmaps to prefill.
+ * @param size The width and height in pixels of the Bitmaps to prefill.
+ */
+ public Builder(int size) {
+ this(size, size);
+ }
+
+ /**
+ * Constructor for a builder that uses the given dimensions as the dimensions of the Bitmaps to prefill.
+ * @param width The width in pixels of the Bitmaps to prefill.
+ * @param height The height in pixels of the Bitmaps to prefill.
+ */
+ public Builder(int width, int height) {
+ if (width <= 0) {
+ throw new IllegalArgumentException("Width must be > 0");
+ }
+ if (height <= 0) {
+ throw new IllegalArgumentException("Height must be > 0");
+ }
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Sets the {@link android.graphics.Bitmap.Config} for the Bitmaps to pre-fill.
+ * @param config The config to use, or null to use Glide's default.
+ * @return This builder.
+ */
+ public Builder setConfig(Bitmap.Config config) {
+ this.config = config;
+ return this;
+ }
+
+ /**
+ * Returns the current {@link android.graphics.Bitmap.Config}.
+ */
+ Bitmap.Config getConfig() {
+ return config;
+ }
+
+ /**
+ * Sets the weight to use to balance how many Bitmaps of this type are prefilled relative to the other requested
+ * types.
+ * @param weight An integer indicating how to balance pre-filling this size and configuration of
+ * {@link android.graphics.Bitmap} against any other sizes/configurations that may be being pre-filled.
+ * @return This builder.
+ */
+ public Builder setWeight(int weight) {
+ if (weight <= 0) {
+ throw new IllegalArgumentException("Weight must be > 0");
+ }
+ this.weight = weight;
+ return this;
+ }
+
+ /**
+ * Returns a new {@link PreFillType}.
+ */
+ PreFillType build() {
+ return new PreFillType(width, height, config, weight);
+ }
+ }
+}
diff --git a/library/src/main/java/com/bumptech/glide/load/model/FileLoader.java b/library/src/main/java/com/bumptech/glide/load/model/FileLoader.java
index 146b9b3d..87d95172 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/FileLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/FileLoader.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.model;
import android.net.Uri;
+
import com.bumptech.glide.load.data.DataFetcher;
import java.io.File;
diff --git a/library/src/main/java/com/bumptech/glide/load/model/GenericLoaderFactory.java b/library/src/main/java/com/bumptech/glide/load/model/GenericLoaderFactory.java
index d8ebf616..9900322f 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/GenericLoaderFactory.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/GenericLoaderFactory.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.model;
import android.content.Context;
+
import com.bumptech.glide.load.data.DataFetcher;
import java.util.HashMap;
@@ -30,6 +31,12 @@ public class GenericLoaderFactory {
}
};
+ private final Context context;
+
+ public GenericLoaderFactory(Context context) {
+ this.context = context.getApplicationContext();
+ }
+
/**
* Removes and returns the registered {@link ModelLoaderFactory} for the given model and resource classes. Returns
* null if no such factory is registered. Clears all cached model loaders.
@@ -92,13 +99,30 @@ public class GenericLoaderFactory {
* {@link ModelLoader} or building a new a new {@link ModelLoader} using registered {@link ModelLoaderFactory}s.
* Returns null if no {@link ModelLoaderFactory} is registered for the given classes.
*
+ * @deprecated Use {@link #buildModelLoader(Class, Class)} instead. Scheduled to be removed in Glide 4.0.
* @param modelClass The model class.
* @param resourceClass The resource class.
+ * @param context Unused
* @param <T> The type of the model.
* @param <Y> The type of the resource.
*/
+ @Deprecated
public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass,
- Context context) {
+ Context context) {
+ return buildModelLoader(modelClass, resourceClass);
+ }
+
+ /**
+ * Returns a {@link ModelLoader} for the given model and resource classes by either returning a cached
+ * {@link ModelLoader} or building a new a new {@link ModelLoader} using registered {@link ModelLoaderFactory}s.
+ * Returns null if no {@link ModelLoaderFactory} is registered for the given classes.
+ *
+ * @param modelClass The model class.
+ * @param resourceClass The resource class.
+ * @param <T> The type of the model.
+ * @param <Y> The type of the resource.
+ */
+ public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
if (result != null) {
// We've already tried to create a model loader and can't with the currently registered set of factories,
@@ -152,7 +176,6 @@ public class GenericLoaderFactory {
result = resourceToFactories.get(resourceClass);
}
-
if (result == null) {
for (Class<? super T> registeredModelClass : modelClassToResourceFactories.keySet()) {
// This accounts for model subclasses, our map only works for exact matches. We should however still
diff --git a/library/src/main/java/com/bumptech/glide/load/model/ImageVideoModelLoader.java b/library/src/main/java/com/bumptech/glide/load/model/ImageVideoModelLoader.java
index 0e7c3763..3d057bac 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/ImageVideoModelLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/ImageVideoModelLoader.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.model;
import android.os.ParcelFileDescriptor;
import android.util.Log;
+
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
diff --git a/library/src/main/java/com/bumptech/glide/load/model/ModelCache.java b/library/src/main/java/com/bumptech/glide/load/model/ModelCache.java
index 5a46cde6..55c0de0c 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/ModelCache.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/ModelCache.java
@@ -35,8 +35,8 @@ public class ModelCache<A, B> {
* Get a value.
*
* @param model The model.
- * @param width The width of the view the image is being loaded into.
- * @param height The height of the view the image is being loaded into.
+ * @param width The width in pixels of the view the image is being loaded into.
+ * @param height The height in pixels of the view the image is being loaded into.
*
* @return The cached result, or null.
*/
@@ -51,8 +51,8 @@ public class ModelCache<A, B> {
* Add a value.
*
* @param model The model.
- * @param width The width of the view the image is being loaded into.
- * @param height The height of the view the image is being loaded into.
+ * @param width The width in pixels of the view the image is being loaded into.
+ * @param height The height in pixels of the view the image is being loaded into.
* @param value The value to store.
*/
public void put(A model, int width, int height, B value) {
@@ -60,14 +60,15 @@ public class ModelCache<A, B> {
cache.put(key, value);
}
- private static final class ModelKey<A> {
+ // Visible for testing.
+ static final class ModelKey<A> {
private static final Queue<ModelKey<?>> KEY_QUEUE = Util.createQueue(0);
private int height;
private int width;
private A model;
- public static <A> ModelKey<A> get(A model, int width, int height) {
+ static <A> ModelKey<A> get(A model, int width, int height) {
@SuppressWarnings("unchecked")
ModelKey<A> modelKey = (ModelKey<A>) KEY_QUEUE.poll();
if (modelKey == null) {
@@ -92,26 +93,11 @@ public class ModelCache<A, B> {
@Override
public boolean equals(Object o) {
- if (this == o) {
- return true;
+ if (o instanceof ModelKey) {
+ ModelKey other = (ModelKey) o;
+ return width == other.width && height == other.height && model.equals(other.model);
}
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- ModelKey<?> modelKey = (ModelKey<?>) o;
-
- if (height != modelKey.height) {
- return false;
- }
- if (width != modelKey.width) {
- return false;
- }
- if (!model.equals(modelKey.model)) {
- return false;
- }
-
- return true;
+ return false;
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/ModelLoader.java b/library/src/main/java/com/bumptech/glide/load/model/ModelLoader.java
index f028209a..164f1d72 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/ModelLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/ModelLoader.java
@@ -37,8 +37,8 @@ public interface ModelLoader<T, Y> {
* </p>
*
* @param model The model representing the resource.
- * @param width The width of the view or target the resource will be loaded into
- * @param height The height of the view or target the resource will be loaded into
+ * @param width The width in pixels of the view or target the resource will be loaded into
+ * @param height The height in pixels of the view or target the resource will be loaded into
* @return A {@link DataFetcher} that can obtain the data the resource can be decoded from if the resource is not
* cached, or null if no valid {@link com.bumptech.glide.load.data.DataFetcher} could be constructed.
*/
diff --git a/library/src/main/java/com/bumptech/glide/load/model/ResourceLoader.java b/library/src/main/java/com/bumptech/glide/load/model/ResourceLoader.java
index 06bb1e55..efc2bd6a 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/ResourceLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/ResourceLoader.java
@@ -4,6 +4,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
+
import com.bumptech.glide.load.data.DataFetcher;
/**
diff --git a/library/src/main/java/com/bumptech/glide/load/model/StreamEncoder.java b/library/src/main/java/com/bumptech/glide/load/model/StreamEncoder.java
index c4f1a711..1022754d 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/StreamEncoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/StreamEncoder.java
@@ -25,8 +25,8 @@ public class StreamEncoder implements Encoder<InputStream> {
}
return true;
} catch (IOException e) {
- if (Log.isLoggable(TAG, Log.WARN)) {
- Log.w(TAG, "Failed to encode data onto the OutputStream", e);
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Failed to encode data onto the OutputStream", e);
}
return false;
} finally {
diff --git a/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java b/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java
index a8e793fc..efdf666c 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.model;
import android.net.Uri;
+
import com.bumptech.glide.load.data.DataFetcher;
import java.io.File;
diff --git a/library/src/main/java/com/bumptech/glide/load/model/UriLoader.java b/library/src/main/java/com/bumptech/glide/load/model/UriLoader.java
index 6120db45..30db4a6c 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/UriLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/UriLoader.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.load.model;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
+
import com.bumptech.glide.load.data.DataFetcher;
/**
diff --git a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorFileLoader.java b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorFileLoader.java
index 89590369..2431df3e 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorFileLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorFileLoader.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.load.model.file_descriptor;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.FileLoader;
import com.bumptech.glide.load.model.GenericLoaderFactory;
@@ -24,8 +25,7 @@ public class FileDescriptorFileLoader extends FileLoader<ParcelFileDescriptor>
public static class Factory implements ModelLoaderFactory<File, ParcelFileDescriptor> {
@Override
public ModelLoader<File, ParcelFileDescriptor> build(Context context, GenericLoaderFactory factories) {
- return new FileDescriptorFileLoader(factories.buildModelLoader(Uri.class, ParcelFileDescriptor.class,
- context));
+ return new FileDescriptorFileLoader(factories.buildModelLoader(Uri.class, ParcelFileDescriptor.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorResourceLoader.java b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorResourceLoader.java
index b69db440..0f107bd1 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorResourceLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorResourceLoader.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.load.model.file_descriptor;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
@@ -23,7 +24,7 @@ public class FileDescriptorResourceLoader extends ResourceLoader<ParcelFileDescr
@Override
public ModelLoader<Integer, ParcelFileDescriptor> build(Context context, GenericLoaderFactory factories) {
return new FileDescriptorResourceLoader(context, factories.buildModelLoader(Uri.class,
- ParcelFileDescriptor.class, context));
+ ParcelFileDescriptor.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorStringLoader.java b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorStringLoader.java
index 23eead66..c6f335fa 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorStringLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorStringLoader.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.load.model.file_descriptor;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
@@ -22,8 +23,7 @@ public class FileDescriptorStringLoader extends StringLoader<ParcelFileDescripto
public static class Factory implements ModelLoaderFactory<String, ParcelFileDescriptor> {
@Override
public ModelLoader<String, ParcelFileDescriptor> build(Context context, GenericLoaderFactory factories) {
- return new FileDescriptorStringLoader(factories.buildModelLoader(Uri.class, ParcelFileDescriptor.class,
- context));
+ return new FileDescriptorStringLoader(factories.buildModelLoader(Uri.class, ParcelFileDescriptor.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorUriLoader.java b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorUriLoader.java
index 84a90f56..d950461a 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorUriLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/file_descriptor/FileDescriptorUriLoader.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.load.model.file_descriptor;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.FileDescriptorAssetPathFetcher;
@@ -25,7 +26,7 @@ public class FileDescriptorUriLoader extends UriLoader<ParcelFileDescriptor> imp
@Override
public ModelLoader<Uri, ParcelFileDescriptor> build(Context context, GenericLoaderFactory factories) {
return new FileDescriptorUriLoader(context, factories.buildModelLoader(GlideUrl.class,
- ParcelFileDescriptor.class, context));
+ ParcelFileDescriptor.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java
index a3af9053..a319c347 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java
@@ -4,10 +4,10 @@ import android.content.Context;
import android.text.TextUtils;
import com.bumptech.glide.Glide;
-import com.bumptech.glide.load.model.ModelCache;
+import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;
+import com.bumptech.glide.load.model.ModelCache;
import com.bumptech.glide.load.model.ModelLoader;
-import com.bumptech.glide.load.data.DataFetcher;
import java.io.InputStream;
@@ -15,7 +15,7 @@ import java.io.InputStream;
* A base class for loading images over http/https. Can be subclassed for use with any model that can be translated
* in to {@link java.io.InputStream} data.
*
- * @param <T> The type of the model
+ * @param <T> The type of the model.
*/
public abstract class BaseGlideUrlLoader<T> implements StreamModelLoader<T> {
private final ModelLoader<GlideUrl, InputStream> concreteLoader;
@@ -64,10 +64,10 @@ public abstract class BaseGlideUrlLoader<T> implements StreamModelLoader<T> {
/**
* Get a valid url http:// or https:// for the given model and dimensions as a string.
*
- * @param model The model
- * @param width The width of the view/target the image will be loaded into
- * @param height The height of the view/target the image will be loaded into
- * @return The String url
+ * @param model The model.
+ * @param width The width in pixels of the view/target the image will be loaded into.
+ * @param height The height in pixels of the view/target the image will be loaded into.
+ * @return The String url.
*/
protected abstract String getUrl(T model, int width, int height);
}
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/HttpUrlGlideUrlLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/HttpUrlGlideUrlLoader.java
index 694537bd..3ee3060d 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/HttpUrlGlideUrlLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/HttpUrlGlideUrlLoader.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.model.stream;
import android.content.Context;
+
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.HttpUrlFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/MediaStoreStreamLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/MediaStoreStreamLoader.java
index e069fd77..980997a6 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/MediaStoreStreamLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/MediaStoreStreamLoader.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.model.stream;
import android.content.Context;
import android.net.Uri;
+
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.MediaStoreThumbFetcher;
import com.bumptech.glide.load.model.ModelLoader;
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamByteArrayLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamByteArrayLoader.java
index a323d0c3..3f0277dc 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamByteArrayLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamByteArrayLoader.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.model.stream;
import android.content.Context;
+
import com.bumptech.glide.load.data.ByteArrayFetcher;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
@@ -22,7 +23,7 @@ public class StreamByteArrayLoader implements StreamModelLoader<byte[]> {
/**
* @deprecated Use {@link com.bumptech.glide.GenericRequestBuilder#signature(com.bumptech.glide.load.Key)}
- * and the empty constructor instead.
+ * and the empty constructor instead. Scheduled to be removed in Glide 4.0.
*/
@Deprecated
public StreamByteArrayLoader(String id) {
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamFileLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamFileLoader.java
index 3042a896..1aca470a 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamFileLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamFileLoader.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.model.stream;
import android.content.Context;
import android.net.Uri;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.FileLoader;
import com.bumptech.glide.load.model.GenericLoaderFactory;
@@ -22,7 +23,7 @@ public class StreamFileLoader extends FileLoader<InputStream> implements StreamM
public static class Factory implements ModelLoaderFactory<File, InputStream> {
@Override
public ModelLoader<File, InputStream> build(Context context, GenericLoaderFactory factories) {
- return new StreamFileLoader(factories.buildModelLoader(Uri.class, InputStream.class, context));
+ return new StreamFileLoader(factories.buildModelLoader(Uri.class, InputStream.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamResourceLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamResourceLoader.java
index a385d3cc..a3825574 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamResourceLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamResourceLoader.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.model.stream;
import android.content.Context;
import android.net.Uri;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
@@ -22,7 +23,7 @@ public class StreamResourceLoader extends ResourceLoader<InputStream> implements
@Override
public ModelLoader<Integer, InputStream> build(Context context, GenericLoaderFactory factories) {
- return new StreamResourceLoader(context, factories.buildModelLoader(Uri.class, InputStream.class, context));
+ return new StreamResourceLoader(context, factories.buildModelLoader(Uri.class, InputStream.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamStringLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamStringLoader.java
index 1f951ee4..80bbb7af 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamStringLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamStringLoader.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.model.stream;
import android.content.Context;
import android.net.Uri;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
@@ -22,7 +23,7 @@ public class StreamStringLoader extends StringLoader<InputStream> implements Str
public static class Factory implements ModelLoaderFactory<String, InputStream> {
@Override
public ModelLoader<String, InputStream> build(Context context, GenericLoaderFactory factories) {
- return new StreamStringLoader(factories.buildModelLoader(Uri.class, InputStream.class, context));
+ return new StreamStringLoader(factories.buildModelLoader(Uri.class, InputStream.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUriLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUriLoader.java
index 3b15b2f7..086f4c4c 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUriLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUriLoader.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.model.stream;
import android.content.Context;
import android.net.Uri;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.StreamAssetPathFetcher;
@@ -28,7 +29,7 @@ public class StreamUriLoader extends UriLoader<InputStream> implements StreamMod
@Override
public ModelLoader<Uri, InputStream> build(Context context, GenericLoaderFactory factories) {
- return new StreamUriLoader(context, factories.buildModelLoader(GlideUrl.class, InputStream.class, context));
+ return new StreamUriLoader(context, factories.buildModelLoader(GlideUrl.class, InputStream.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUrlLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUrlLoader.java
index c8d35252..ec6a207d 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUrlLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/StreamUrlLoader.java
@@ -1,8 +1,9 @@
package com.bumptech.glide.load.model.stream;
import android.content.Context;
-import com.bumptech.glide.load.model.GlideUrl;
+
import com.bumptech.glide.load.model.GenericLoaderFactory;
+import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.UrlLoader;
@@ -23,7 +24,7 @@ public class StreamUrlLoader extends UrlLoader<InputStream> {
public static class Factory implements ModelLoaderFactory<URL, InputStream> {
@Override
public ModelLoader<URL, InputStream> build(Context context, GenericLoaderFactory factories) {
- return new StreamUrlLoader(factories.buildModelLoader(GlideUrl.class, InputStream.class, context));
+ return new StreamUrlLoader(factories.buildModelLoader(GlideUrl.class, InputStream.class));
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/SimpleResource.java b/library/src/main/java/com/bumptech/glide/load/resource/SimpleResource.java
index 4dca7fb1..33ccbb8a 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/SimpleResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/SimpleResource.java
@@ -13,6 +13,9 @@ public class SimpleResource<T> implements Resource<T> {
protected final T data;
public SimpleResource(T data) {
+ if (data == null) {
+ throw new NullPointerException("Data must not be null");
+ }
this.data = data;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDecoder.java
index 7ca6f496..36c4df17 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDecoder.java
@@ -1,8 +1,9 @@
package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
-import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
+
import com.bumptech.glide.load.DecodeFormat;
+import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
/**
* A bitmap decoder for a given resource type.
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDrawableResource.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDrawableResource.java
index 616204d5..9d062e17 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDrawableResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapDrawableResource.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.bitmap;
import android.graphics.drawable.BitmapDrawable;
+
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.drawable.DrawableResource;
import com.bumptech.glide.util.Util;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoder.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoder.java
index 5bd2f935..ab6d8df8 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoder.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
import android.util.Log;
+
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.util.LogTime;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapResource.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapResource.java
index 0ce032ea..10785c6b 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapResource.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.util.Util;
@@ -12,7 +13,28 @@ public class BitmapResource implements Resource<Bitmap> {
private final Bitmap bitmap;
private final BitmapPool bitmapPool;
+ /**
+ * Returns a new {@link BitmapResource} wrapping the given {@link Bitmap} if the Bitmap is non-null or null if the
+ * given Bitmap is null.
+ *
+ * @param bitmap A Bitmap.
+ * @param bitmapPool A non-null {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool}.
+ */
+ public static BitmapResource obtain(Bitmap bitmap, BitmapPool bitmapPool) {
+ if (bitmap == null) {
+ return null;
+ } else {
+ return new BitmapResource(bitmap, bitmapPool);
+ }
+ }
+
public BitmapResource(Bitmap bitmap, BitmapPool bitmapPool) {
+ if (bitmap == null) {
+ throw new NullPointerException("Bitmap must not be null");
+ }
+ if (bitmapPool == null) {
+ throw new NullPointerException("BitmapPool must not be null");
+ }
this.bitmap = bitmap;
this.bitmapPool = bitmapPool;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.java
index 3195504b..c3624b1c 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.resource.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
@@ -52,7 +53,7 @@ public abstract class BitmapTransformation implements Transformation<Bitmap> {
if (toTransform.equals(transformed)) {
result = resource;
} else {
- result = new BitmapResource(transformed, bitmapPool);
+ result = BitmapResource.obtain(transformed, bitmapPool);
}
return result;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java
index e6143197..904a7c45 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java
@@ -105,6 +105,7 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
final byte[] bytesForOptions = byteArrayPool.getBytes();
final byte[] bytesForStream = byteArrayPool.getBytes();
final BitmapFactory.Options options = getDefaultOptions();
+
// TODO(#126): when the framework handles exceptions better, consider removing.
final ExceptionCatchingInputStream stream =
ExceptionCatchingInputStream.obtain(new RecyclableBufferedInputStream(is, bytesForStream));
@@ -134,19 +135,13 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
final int inHeight = inDimens[1];
final int degreesToRotate = TransformationUtils.getExifOrientationDegrees(orientation);
- final int sampleSize;
- if (degreesToRotate == 90 || degreesToRotate == 270) {
- // If we're rotating the image +-90 degrees, we need to downsample accordingly so the image width is
- // decreased to near our target's height and the image height is decreased to near our target width.
- sampleSize = getSampleSize(inHeight, inWidth, outWidth, outHeight);
- } else {
- sampleSize = getSampleSize(inWidth, inHeight, outWidth, outHeight);
- }
+ final int sampleSize = getRoundedSampleSize(degreesToRotate, inWidth, inHeight, outWidth, outHeight);
final Bitmap downsampled =
- downsampleWithSize(stream, options, pool, inWidth, inHeight, sampleSize, decodeFormat);
+ downsampleWithSize(stream, options, pool, inWidth, inHeight, sampleSize,
+ decodeFormat);
- // BitmapDecoder swallows exceptions during decodes and in some cases when inBitmap is non null, may catch
+ // BitmapFactory swallows exceptions during decodes and in some cases when inBitmap is non null, may catch
// and log a stack trace but still return a non null bitmap. To avoid displaying partially decoded bitmaps,
// we catch exceptions reading from the stream in our ExceptionCatchingInputStream and throw them here.
final Exception streamException = stream.getException();
@@ -172,15 +167,37 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
}
}
- protected Bitmap downsampleWithSize(InputStream is, BitmapFactory.Options options,
- BitmapPool pool, int inWidth, int inHeight, int sampleSize, DecodeFormat decodeFormat) {
+ private int getRoundedSampleSize(int degreesToRotate, int inWidth, int inHeight, int outWidth, int outHeight) {
+ final int exactSampleSize;
+ if (degreesToRotate == 90 || degreesToRotate == 270) {
+ // If we're rotating the image +-90 degrees, we need to downsample accordingly so the image width is
+ // decreased to near our target's height and the image height is decreased to near our target width.
+ exactSampleSize = getSampleSize(inHeight, inWidth, outWidth, outHeight);
+ } else {
+ exactSampleSize = getSampleSize(inWidth, inHeight, outWidth, outHeight);
+ }
+
+ // BitmapFactory only accepts powers of 2, so it will round down to the nearest power of two that is less than
+ // or equal to the sample size we provide. Because we need to estimate the final image width and height to
+ // re-use Bitmaps, we mirror BitmapFactory's calculation here. For bug, see issue #224. For algorithm see
+ // http://stackoverflow.com/a/17379704/800716.
+ final int powerOfTwoSampleSize = exactSampleSize == 0 ? 0 : Integer.highestOneBit(exactSampleSize - 1);
+
+ // Although functionally equivalent to 0 for BitmapFactory, 1 is a safer default for our code than 0.
+ return Math.max(1, powerOfTwoSampleSize);
+ }
+
+ private Bitmap downsampleWithSize(ExceptionCatchingInputStream is, BitmapFactory.Options options, BitmapPool pool,
+ int inWidth, int inHeight, int sampleSize, DecodeFormat decodeFormat) {
// Prior to KitKat, the inBitmap size must exactly match the size of the bitmap we're decoding.
Bitmap.Config config = getConfig(is, decodeFormat);
options.inSampleSize = sampleSize;
options.inPreferredConfig = config;
if ((options.inSampleSize == 1 || Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) && shouldUsePool(is)) {
+ int targetWidth = (int) Math.ceil(inWidth / (double) sampleSize);
+ int targetHeight = (int) Math.ceil(inHeight / (double) sampleSize);
// BitmapFactory will clear out the Bitmap before writing to it, so getDirty is safe.
- setInBitmap(options, pool.getDirty(inWidth, inHeight, config));
+ setInBitmap(options, pool.getDirty(targetWidth, targetHeight, config));
}
return decodeStream(is, options);
}
@@ -265,15 +282,14 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
* android.graphics.BitmapFactory.Options)}.
* @return an array containing the dimensions of the image in the form {width, height}.
*/
- public int[] getDimensions(InputStream is, BitmapFactory.Options options) {
+ public int[] getDimensions(ExceptionCatchingInputStream is, BitmapFactory.Options options) {
options.inJustDecodeBounds = true;
decodeStream(is, options);
options.inJustDecodeBounds = false;
return new int[] { options.outWidth, options.outHeight };
}
-
- private static Bitmap decodeStream(InputStream is, BitmapFactory.Options options) {
+ private static Bitmap decodeStream(ExceptionCatchingInputStream is, BitmapFactory.Options options) {
if (options.inJustDecodeBounds) {
// This is large, but jpeg headers are not size bounded so we need something large enough to minimize
// the possibility of not being able to fit enough of the header in the buffer to get the image size so
@@ -281,6 +297,11 @@ public abstract class Downsampler implements BitmapDecoder<InputStream> {
// original size each time we use up the buffer space without passing the mark so this is a maximum
// bound on the buffer size, not a default. Most of the time we won't go past our pre-allocated 16kb.
is.mark(MARK_POSITION);
+ } else {
+ // Once we've read the image header, we no longer need to allow the buffer to expand in size. To avoid
+ // unnecessary allocations reading image data, we fix the mark limit so that it is no larger than our
+ // current buffer size here. See issue #225.
+ is.fixMarkLimit();
}
final Bitmap result = BitmapFactory.decodeStream(is, null, options);
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDataLoadProvider.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDataLoadProvider.java
index cbab4275..af27bc60 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDataLoadProvider.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDataLoadProvider.java
@@ -4,13 +4,13 @@ import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
import com.bumptech.glide.load.DecodeFormat;
-import com.bumptech.glide.provider.DataLoadProvider;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.NullEncoder;
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
+import com.bumptech.glide.provider.DataLoadProvider;
import java.io.File;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDecoder.java
index 3eb38934..f6f2bfbe 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/FileDescriptorBitmapDecoder.java
@@ -3,11 +3,12 @@ package com.bumptech.glide.load.resource.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.Glide;
-import com.bumptech.glide.load.engine.Resource;
+import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.ResourceDecoder;
+import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
-import com.bumptech.glide.load.DecodeFormat;
import java.io.IOException;
@@ -42,11 +43,7 @@ public class FileDescriptorBitmapDecoder implements ResourceDecoder<ParcelFileDe
@Override
public Resource<Bitmap> decode(ParcelFileDescriptor source, int width, int height) throws IOException {
Bitmap bitmap = bitmapDecoder.decode(source, bitmapPool, width, height, decodeFormat);
- if (bitmap == null) {
- return null;
- } else {
- return new BitmapResource(bitmap, bitmapPool);
- }
+ return BitmapResource.obtain(bitmap, bitmapPool);
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/GlideBitmapDrawable.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/GlideBitmapDrawable.java
index e2589131..27e05185 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/GlideBitmapDrawable.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/GlideBitmapDrawable.java
@@ -29,6 +29,10 @@ public class GlideBitmapDrawable extends GlideDrawable {
}
GlideBitmapDrawable(Resources res, BitmapState state) {
+ if (state == null) {
+ throw new NullPointerException("BitmapState must not be null");
+ }
+
this.state = state;
final int targetDensity;
if (res != null) {
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageHeaderParser.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageHeaderParser.java
index 593bbb42..cd787817 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageHeaderParser.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageHeaderParser.java
@@ -1,5 +1,11 @@
package com.bumptech.glide.load.resource.bitmap;
+import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.GIF;
+import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.JPEG;
+import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.PNG;
+import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.PNG_A;
+import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.UNKNOWN;
+
import android.util.Log;
import java.io.IOException;
@@ -8,12 +14,6 @@ import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.GIF;
-import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.JPEG;
-import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.PNG;
-import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.PNG_A;
-import static com.bumptech.glide.load.resource.bitmap.ImageHeaderParser.ImageType.UNKNOWN;
-
/**
* A class for parsing the exif orientation and other data from an image header.
*/
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoBitmapDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoBitmapDecoder.java
index 5edf2ceb..58cb6036 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoBitmapDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoBitmapDecoder.java
@@ -3,8 +3,9 @@ package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
import android.util.Log;
-import com.bumptech.glide.load.engine.Resource;
+
import com.bumptech.glide.load.ResourceDecoder;
+import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.model.ImageVideoWrapper;
import java.io.IOException;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoDataLoadProvider.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoDataLoadProvider.java
index b02e46c1..002a48f9 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoDataLoadProvider.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/ImageVideoDataLoadProvider.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
+
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java
index b0811526..8699022b 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java
@@ -17,6 +17,8 @@ package com.bumptech.glide.load.resource.bitmap;
* limitations under the License.
*/
+import android.util.Log;
+
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -36,32 +38,33 @@ import java.io.InputStream;
* </pre>
*/
public class RecyclableBufferedInputStream extends FilterInputStream {
+ private static final String TAG = "BufferedIs";
/**
* The buffer containing the current bytes read from the target InputStream.
*/
- protected volatile byte[] buf;
+ private volatile byte[] buf;
/**
* The total number of bytes inside the byte array {@code buf}.
*/
- protected int count;
+ private int count;
/**
* The current limit, which when passed, invalidates the current mark.
*/
- protected int marklimit;
+ private int marklimit;
/**
* The currently marked position. -1 indicates no mark has been set or the
* mark has been invalidated.
*/
- protected int markpos = -1;
+ private int markpos = -1;
/**
* The current position within the byte array {@code buf}.
*/
- protected int pos;
+ private int pos;
public RecyclableBufferedInputStream(InputStream in, byte[] buffer) {
super(in);
@@ -95,6 +98,17 @@ public class RecyclableBufferedInputStream extends FilterInputStream {
}
/**
+ * Reduces the mark limit to match the current buffer length to prevent the buffer from
+ * continuing to increase in size.
+ *
+ * <p>Subsequent calls to {@link #mark(int)} will be obeyed and may cause the buffer size
+ * to increase.
+ */
+ public synchronized void fixMarkLimit() {
+ marklimit = buf.length;
+ }
+
+ /**
* Closes this stream. The source stream is closed and any resources
* associated with it are released.
*
@@ -134,6 +148,9 @@ public class RecyclableBufferedInputStream extends FilterInputStream {
if (newLength > marklimit) {
newLength = marklimit;
}
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "allocate buffer of length: " + newLength);
+ }
byte[] newbuf = new byte[newLength];
System.arraycopy(localBuf, 0, newbuf, 0, localBuf.length);
// Reassign buf, which will invalidate any local references
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDataLoadProvider.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDataLoadProvider.java
index ae89ec9f..e05e4845 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDataLoadProvider.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDataLoadProvider.java
@@ -3,13 +3,13 @@ package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
import com.bumptech.glide.load.DecodeFormat;
-import com.bumptech.glide.provider.DataLoadProvider;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.model.StreamEncoder;
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
+import com.bumptech.glide.provider.DataLoadProvider;
import java.io.File;
import java.io.InputStream;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDecoder.java
index b9d8a8df..407b8cb6 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/StreamBitmapDecoder.java
@@ -2,10 +2,11 @@ package com.bumptech.glide.load.resource.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
+
import com.bumptech.glide.Glide;
-import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.DecodeFormat;
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.InputStream;
@@ -47,11 +48,7 @@ public class StreamBitmapDecoder implements ResourceDecoder<InputStream, Bitmap>
@Override
public Resource<Bitmap> decode(InputStream source, int width, int height) {
Bitmap bitmap = downsampler.decode(source, bitmapPool, width, height, decodeFormat);
- if (bitmap == null) {
- return null;
- } else {
- return new BitmapResource(bitmap, bitmapPool);
- }
+ return BitmapResource.obtain(bitmap, bitmapPool);
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
index 2f3a3ef1..2a7d5f9a 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
@@ -9,6 +9,7 @@ import android.graphics.RectF;
import android.media.ExifInterface;
import android.os.Build;
import android.util.Log;
+
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
/**
@@ -30,8 +31,8 @@ public final class TransformationUtils {
* @param recycled A mutable Bitmap with dimensions width and height that we can load the cropped portion of toCrop
* into.
* @param toCrop The Bitmap to resize.
- * @param width The width of the final Bitmap.
- * @param height The height of the final Bitmap.
+ * @param width The width in pixels of the final Bitmap.
+ * @param height The height in pixels of the final Bitmap.
* @return The resized Bitmap (will be recycled if recycled is not null).
*/
public static Bitmap centerCrop(Bitmap recycled, Bitmap toCrop, int width, int height) {
@@ -77,8 +78,8 @@ public final class TransformationUtils {
*
* @param toFit The Bitmap to shrink.
* @param pool The BitmapPool to try to reuse a bitmap from.
- * @param width The width the final image will fit within.
- * @param height The height the final image will fit within.
+ * @param width The width in pixels the final image will fit within.
+ * @param height The height in pixels the final image will fit within.
* @return A new Bitmap shrunk to fit within the given dimensions, or toFit if toFit's width or height matches the
* given dimensions and toFit fits within the given dimensions
*/
@@ -149,22 +150,18 @@ public final class TransformationUtils {
* Returns a matrix with rotation set based on Exif orientation tag.
* If the orientation is undefined or 0 null is returned.
*
+ * @deprecated No longer used by Glide, scheduled to be removed in Glide 4.0
* @param pathToOriginal Path to original image file that may have exif data.
* @return A rotation in degrees based on exif orientation
*/
@TargetApi(Build.VERSION_CODES.ECLAIR)
+ @Deprecated
public static int getOrientation(String pathToOriginal) {
int degreesToRotate = 0;
try {
ExifInterface exif = new ExifInterface(pathToOriginal);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
- if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
- degreesToRotate = 90;
- } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
- degreesToRotate = 180;
- } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
- degreesToRotate = 270;
- }
+ return getExifOrientationDegrees(orientation);
} catch (Exception e) {
if (Log.isLoggable(TAG, Log.ERROR)) {
Log.e(TAG, "Unable to get orientation for image with path=" + pathToOriginal, e);
@@ -177,10 +174,12 @@ public final class TransformationUtils {
* This is an expensive operation that copies the image in place with the pixels rotated.
* If possible rather use getOrientationMatrix, and set that as the imageMatrix on an ImageView.
*
+ * @deprecated No longer used by Glide, scheduled to be removed in Glide 4.0
* @param pathToOriginal Path to original image file that may have exif data.
* @param imageToOrient Image Bitmap to orient.
* @return The oriented bitmap. May be the imageToOrient without modification, or a new Bitmap.
*/
+ @Deprecated
public static Bitmap orientImage(String pathToOriginal, Bitmap imageToOrient) {
int degreesToRotate = getOrientation(pathToOriginal);
return rotateImage(imageToOrient, degreesToRotate);
@@ -255,7 +254,36 @@ public final class TransformationUtils {
* @return The rotated and/or flipped image or toOrient if no rotation or flip was necessary.
*/
public static Bitmap rotateImageExif(Bitmap toOrient, BitmapPool pool, int exifOrientation) {
+ if (exifOrientation == ExifInterface.ORIENTATION_NORMAL
+ || exifOrientation == ExifInterface.ORIENTATION_UNDEFINED) {
+ return toOrient;
+ }
final Matrix matrix = new Matrix();
+ initializeMatrixForRotation(exifOrientation, matrix);
+
+ // From Bitmap.createBitmap.
+ final RectF newRect = new RectF(0, 0, toOrient.getWidth(), toOrient.getHeight());
+ matrix.mapRect(newRect);
+
+ final int newWidth = Math.round(newRect.width());
+ final int newHeight = Math.round(newRect.height());
+
+ Bitmap result = pool.get(newWidth, newHeight, toOrient.getConfig());
+ if (result == null) {
+ result = Bitmap.createBitmap(newWidth, newHeight, toOrient.getConfig());
+ }
+
+ matrix.postTranslate(-newRect.left, -newRect.top);
+
+ final Canvas canvas = new Canvas(result);
+ final Paint paint = new Paint(PAINT_FLAGS);
+ canvas.drawBitmap(toOrient, matrix, paint);
+
+ return result;
+ }
+
+ // Visible for testing.
+ static void initializeMatrixForRotation(int exifOrientation, Matrix matrix) {
switch (exifOrientation) {
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
@@ -281,29 +309,8 @@ public final class TransformationUtils {
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
- // case ExifInterface.ORIENTATION_NORMAL
default:
- return toOrient;
- }
-
- // From Bitmap.createBitmap.
- final RectF newRect = new RectF(0, 0, toOrient.getWidth(), toOrient.getHeight());
- matrix.mapRect(newRect);
-
- final int newWidth = Math.round(newRect.width());
- final int newHeight = Math.round(newRect.height());
-
- Bitmap result = pool.get(newWidth, newHeight, toOrient.getConfig());
- if (result == null) {
- result = Bitmap.createBitmap(newWidth, newHeight, toOrient.getConfig());
+ // Do nothing.
}
-
- matrix.postTranslate(-newRect.left, -newRect.top);
-
- final Canvas canvas = new Canvas(result);
- final Paint paint = new Paint(PAINT_FLAGS);
- canvas.drawBitmap(toOrient, matrix, paint);
-
- return result;
}
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoBitmapDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoBitmapDecoder.java
index 15990462..537b185c 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoBitmapDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoBitmapDecoder.java
@@ -3,8 +3,9 @@ package com.bumptech.glide.load.resource.bitmap;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.ParcelFileDescriptor;
-import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
+
import com.bumptech.glide.load.DecodeFormat;
+import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import java.io.IOException;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java b/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java
index eb29217d..a6368d26 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java
@@ -9,6 +9,9 @@ public class BytesResource implements Resource<byte[]> {
private final byte[] bytes;
public BytesResource(byte[] bytes) {
+ if (bytes == null) {
+ throw new NullPointerException("Bytes must not be null");
+ }
this.bytes = bytes;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/drawable/DrawableResource.java b/library/src/main/java/com/bumptech/glide/load/resource/drawable/DrawableResource.java
index b3efc621..643f7b40 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/drawable/DrawableResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/drawable/DrawableResource.java
@@ -18,6 +18,9 @@ public abstract class DrawableResource<T extends Drawable> implements Resource<T
private boolean returnedOriginalDrawable;
public DrawableResource(T drawable) {
+ if (drawable == null) {
+ throw new NullPointerException("Drawable must not be null!");
+ }
this.drawable = drawable;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/file/StreamFileDataLoadProvider.java b/library/src/main/java/com/bumptech/glide/load/resource/file/StreamFileDataLoadProvider.java
index c31e3a4a..13df0a20 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/file/StreamFileDataLoadProvider.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/file/StreamFileDataLoadProvider.java
@@ -1,12 +1,12 @@
package com.bumptech.glide.load.resource.file;
-import com.bumptech.glide.load.engine.Resource;
-import com.bumptech.glide.provider.DataLoadProvider;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
+import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.model.StreamEncoder;
import com.bumptech.glide.load.resource.NullResourceEncoder;
+import com.bumptech.glide.provider.DataLoadProvider;
import java.io.File;
import java.io.InputStream;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifBitmapProvider.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifBitmapProvider.java
index 5bfdd626..de52039f 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifBitmapProvider.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifBitmapProvider.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.resource.gif;
import android.graphics.Bitmap;
+
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
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 fd5ea782..47e06fb5 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
@@ -11,8 +11,8 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
-
import android.view.Gravity;
+
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.gifdecoder.GifHeader;
import com.bumptech.glide.load.Transformation;
@@ -75,11 +75,15 @@ public class GifDrawable extends GlideDrawable implements GifFrameManager.FrameC
}
GifDrawable(GifState state) {
+ if (state == null) {
+ throw new NullPointerException("GifState must not be null");
+ }
+
this.state = state;
this.decoder = new GifDecoder(state.bitmapProvider);
decoder.setData(state.gifHeader, state.data);
- frameManager = new GifFrameManager(state.context, decoder, state.frameTransformation, state.targetWidth,
- state.targetHeight);
+ frameManager = new GifFrameManager(state.context, decoder, state.targetWidth, state.targetHeight);
+ frameManager.setFrameTransformation(state.frameTransformation);
}
// Visible for testing.
@@ -96,8 +100,15 @@ public class GifDrawable extends GlideDrawable implements GifFrameManager.FrameC
}
public void setFrameTransformation(Transformation<Bitmap> frameTransformation, Bitmap firstFrame) {
+ if (firstFrame == null) {
+ throw new NullPointerException("The first frame of the GIF must not be null");
+ }
+ if (frameTransformation == null) {
+ throw new NullPointerException("The frame transformation must not be null");
+ }
state.frameTransformation = frameTransformation;
state.firstFrame = firstFrame;
+ frameManager.setFrameTransformation(frameTransformation);
}
public GifDecoder getDecoder() {
@@ -313,6 +324,9 @@ public class GifDrawable extends GlideDrawable implements GifFrameManager.FrameC
public GifState(GifHeader header, byte[] data, Context context,
Transformation<Bitmap> frameTransformation, int targetWidth, int targetHeight,
GifDecoder.BitmapProvider provider, BitmapPool bitmapPool, Bitmap firstFrame) {
+ if (firstFrame == null) {
+ throw new NullPointerException("The first frame of the GIF must not be null");
+ }
gifHeader = header;
this.data = data;
this.bitmapPool = bitmapPool;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableLoadProvider.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableLoadProvider.java
index 3e0fe3c1..971847d3 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableLoadProvider.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableLoadProvider.java
@@ -2,14 +2,13 @@ package com.bumptech.glide.load.resource.gif;
import android.content.Context;
-import com.bumptech.glide.load.DecodeFormat;
-import com.bumptech.glide.provider.DataLoadProvider;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.model.StreamEncoder;
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
+import com.bumptech.glide.provider.DataLoadProvider;
import java.io.File;
import java.io.InputStream;
@@ -24,8 +23,8 @@ public class GifDrawableLoadProvider implements DataLoadProvider<InputStream, Gi
private final StreamEncoder sourceEncoder;
private final FileToStreamDecoder<GifDrawable> cacheDecoder;
- public GifDrawableLoadProvider(Context context, BitmapPool bitmapPool, DecodeFormat decodeFormat) {
- decoder = new GifResourceDecoder(context, bitmapPool, decodeFormat);
+ public GifDrawableLoadProvider(Context context, BitmapPool bitmapPool) {
+ decoder = new GifResourceDecoder(context, bitmapPool);
cacheDecoder = new FileToStreamDecoder<GifDrawable>(decoder);
encoder = new GifResourceEncoder(bitmapPool);
sourceEncoder = new StreamEncoder();
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableTransformation.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableTransformation.java
index 9261e0fc..2e17d290 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableTransformation.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawableTransformation.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.gif;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java
index 661e84d9..ad2cdbc7 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameManager.java
@@ -6,6 +6,8 @@ import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
+
+import com.bumptech.glide.GenericRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.load.Encoder;
@@ -14,6 +16,7 @@ import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.NullEncoder;
+import com.bumptech.glide.load.resource.UnitTransformation;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
@@ -22,73 +25,75 @@ import java.security.MessageDigest;
import java.util.UUID;
class GifFrameManager {
- /** 60fps is {@value #MIN_FRAME_DELAY}ms per frame. */
- private static final long MIN_FRAME_DELAY = 1000 / 60;
- private final GifFrameModelLoader frameLoader;
- private final GifFrameResourceDecoder frameResourceDecoder;
private final GifDecoder decoder;
private final Handler mainHandler;
- private final Context context;
- private final Encoder<GifDecoder> sourceEncoder;
- private final Transformation<Bitmap>[] transformation;
private final int targetWidth;
private final int targetHeight;
private final FrameSignature signature;
+ private final GenericRequestBuilder<GifDecoder, GifDecoder, Bitmap, Bitmap> requestBuilder;
+ private boolean isLoadInProgress;
private DelayTarget current;
private DelayTarget next;
+ private Transformation<Bitmap> transformation = UnitTransformation.get();
public interface FrameCallback {
void onFrameRead(int index);
}
- public GifFrameManager(Context context, GifDecoder decoder, Transformation<Bitmap> transformation, int targetWidth,
- int targetHeight) {
- this(context, Glide.get(context).getBitmapPool(), decoder, new Handler(Looper.getMainLooper()), transformation,
- targetWidth, targetHeight);
+ public GifFrameManager(Context context, GifDecoder decoder, int targetWidth, int targetHeight) {
+ this(context, Glide.get(context).getBitmapPool(), decoder, new Handler(Looper.getMainLooper()), targetWidth,
+ targetHeight);
}
- @SuppressWarnings("unchecked")
public GifFrameManager(Context context, BitmapPool bitmapPool, GifDecoder decoder, Handler mainHandler,
- Transformation<Bitmap> transformation, int targetWidth, int targetHeight) {
- if (transformation == null) {
- throw new NullPointerException("Transformation must not be null");
- }
+ int targetWidth, int targetHeight) {
- this.context = context;
- this.frameResourceDecoder = new GifFrameResourceDecoder(bitmapPool);
this.decoder = decoder;
this.mainHandler = mainHandler;
- this.transformation = new Transformation[] {transformation};
this.targetWidth = targetWidth;
this.targetHeight = targetHeight;
- this.frameLoader = new GifFrameModelLoader();
- this.sourceEncoder = NullEncoder.get();
this.signature = new FrameSignature();
+
+ GifFrameResourceDecoder frameResourceDecoder = new GifFrameResourceDecoder(bitmapPool);
+ GifFrameModelLoader frameLoader = new GifFrameModelLoader();
+ Encoder<GifDecoder> sourceEncoder = NullEncoder.get();
+
+ requestBuilder = Glide.with(context)
+ .using(frameLoader, GifDecoder.class)
+ .from(GifDecoder.class)
+ .as(Bitmap.class)
+ .signature(signature)
+ .sourceEncoder(sourceEncoder)
+ .decoder(frameResourceDecoder)
+ .skipMemoryCache(true)
+ .diskCacheStrategy(DiskCacheStrategy.NONE);
}
- Transformation<Bitmap> getTransformation() {
- return transformation[0];
+ public void setFrameTransformation(Transformation<Bitmap> transformation) {
+ if (transformation == null) {
+ throw new NullPointerException("Transformation must not be null");
+ }
+ this.transformation = transformation;
}
+ @SuppressWarnings("unchecked")
public void getNextFrame(FrameCallback cb) {
+ if (isLoadInProgress) {
+ return;
+ }
+ isLoadInProgress = true;
+
decoder.advance();
- long targetTime = SystemClock.uptimeMillis() + Math.max(MIN_FRAME_DELAY, decoder.getNextDelay());
+ long targetTime = SystemClock.uptimeMillis() + decoder.getNextDelay();
next = new DelayTarget(cb, targetTime);
next.setFrameIndex(decoder.getCurrentFrameIndex());
// Use an incrementing signature to make sure we never hit an active resource that matches one of our frames.
signature.increment();
- Glide.with(context)
- .using(frameLoader, GifDecoder.class)
+ requestBuilder
.load(decoder)
- .as(Bitmap.class)
- .signature(signature)
- .sourceEncoder(sourceEncoder)
- .decoder(frameResourceDecoder)
.transform(transformation)
- .skipMemoryCache(true)
- .diskCacheStrategy(DiskCacheStrategy.NONE)
.into(next);
}
@@ -97,14 +102,15 @@ class GifFrameManager {
}
public void clear() {
+ isLoadInProgress = false;
if (current != null) {
- mainHandler.removeCallbacks(current);
Glide.clear(current);
+ mainHandler.removeCallbacks(current);
current = null;
}
if (next != null) {
- mainHandler.removeCallbacks(next);
Glide.clear(next);
+ mainHandler.removeCallbacks(next);
next = null;
}
@@ -135,9 +141,17 @@ class GifFrameManager {
@Override
public void run() {
+ isLoadInProgress = false;
cb.onFrameRead(index);
if (current != null) {
- Glide.clear(current);
+ // TODO: figure out why this is necessary and fix it. See issue #219.
+ final DelayTarget recycleCurrent = current;
+ mainHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Glide.clear(recycleCurrent);
+ }
+ });
}
current = this;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameResourceDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameResourceDecoder.java
index dbc0e172..1815c99d 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameResourceDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameResourceDecoder.java
@@ -1,9 +1,10 @@
package com.bumptech.glide.load.resource.gif;
import android.graphics.Bitmap;
-import com.bumptech.glide.load.engine.Resource;
+
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.load.ResourceDecoder;
+import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapResource;
@@ -17,7 +18,7 @@ class GifFrameResourceDecoder implements ResourceDecoder<GifDecoder, Bitmap> {
@Override
public Resource<Bitmap> decode(GifDecoder source, int width, int height) {
Bitmap bitmap = source.getNextFrame();
- return new BitmapResource(bitmap, bitmapPool);
+ return BitmapResource.obtain(bitmap, bitmapPool);
}
@Override
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceDecoder.java
index f4cbb1e2..55a257fd 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceDecoder.java
@@ -3,11 +3,11 @@ package com.bumptech.glide.load.resource.gif;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.gifdecoder.GifHeader;
import com.bumptech.glide.gifdecoder.GifHeaderParser;
-import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
@@ -31,7 +31,6 @@ public class GifResourceDecoder implements ResourceDecoder<InputStream, GifDrawa
private final Context context;
private final GifHeaderParserPool parserPool;
private final BitmapPool bitmapPool;
- private final DecodeFormat decodeFormat;
private final GifDecoderPool decoderPool;
private final GifBitmapProvider provider;
@@ -39,24 +38,15 @@ public class GifResourceDecoder implements ResourceDecoder<InputStream, GifDrawa
this(context, Glide.get(context).getBitmapPool());
}
- public GifResourceDecoder(Context context, DecodeFormat decodeFormat) {
- this(context, Glide.get(context).getBitmapPool(), decodeFormat);
- }
-
public GifResourceDecoder(Context context, BitmapPool bitmapPool) {
- this(context, bitmapPool, DecodeFormat.DEFAULT);
- }
-
- public GifResourceDecoder(Context context, BitmapPool bitmapPool, DecodeFormat decodeFormat) {
- this(context, bitmapPool, decodeFormat, PARSER_POOL, DECODER_POOL);
+ this(context, bitmapPool, PARSER_POOL, DECODER_POOL);
}
// Visible for testing.
- GifResourceDecoder(Context context, BitmapPool bitmapPool, DecodeFormat decodeFormat,
- GifHeaderParserPool parserPool, GifDecoderPool decoderPool) {
+ GifResourceDecoder(Context context, BitmapPool bitmapPool, GifHeaderParserPool parserPool,
+ GifDecoderPool decoderPool) {
this.context = context;
this.bitmapPool = bitmapPool;
- this.decodeFormat = decodeFormat;
this.decoderPool = decoderPool;
this.provider = new GifBitmapProvider(bitmapPool);
this.parserPool = parserPool;
@@ -67,8 +57,6 @@ public class GifResourceDecoder implements ResourceDecoder<InputStream, GifDrawa
byte[] data = inputStreamToBytes(source);
final GifHeaderParser parser = parserPool.obtain(data);
final GifDecoder decoder = decoderPool.obtain(provider);
- decoder.setPreferredConfig(decodeFormat == DecodeFormat.PREFER_RGB_565
- ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888);
try {
return decode(data, width, height, parser, decoder);
} finally {
@@ -85,6 +73,10 @@ public class GifResourceDecoder implements ResourceDecoder<InputStream, GifDrawa
}
Bitmap firstFrame = decodeFirstFrame(decoder, header, data);
+ if (firstFrame == null) {
+ return null;
+ }
+
Transformation<Bitmap> unitTransformation = UnitTransformation.get();
GifDrawable gifDrawable = new GifDrawable(context, provider, bitmapPool, unitTransformation, width, height,
@@ -152,6 +144,7 @@ public class GifResourceDecoder implements ResourceDecoder<InputStream, GifDrawa
}
public synchronized void release(GifHeaderParser parser) {
+ parser.clear();
pool.offer(parser);
}
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceEncoder.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceEncoder.java
index ab2e14c6..df3b51fb 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceEncoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifResourceEncoder.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.resource.gif;
import android.graphics.Bitmap;
import android.util.Log;
+
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.gifdecoder.GifHeader;
import com.bumptech.glide.gifdecoder.GifHeaderParser;
@@ -110,6 +111,7 @@ public class GifResourceEncoder implements ResourceEncoder<GifDrawable> {
private Resource<Bitmap> getTransformedFrame(Bitmap currentFrame, Transformation<Bitmap> transformation,
GifDrawable drawable) {
+ // TODO: what if current frame is null?
Resource<Bitmap> bitmapResource = factory.buildFrameResource(currentFrame, bitmapPool);
Resource<Bitmap> transformedResource = transformation.transform(bitmapResource,
drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapper.java b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapper.java
index b5d73154..0b3b62ba 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapper.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapper.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.gifbitmap;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.gif.GifDrawable;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResource.java b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResource.java
index 7e10e008..0fcd2205 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResource.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.gifbitmap;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.gif.GifDrawable;
@@ -11,6 +12,9 @@ public class GifBitmapWrapperResource implements Resource<GifBitmapWrapper> {
private final GifBitmapWrapper data;
public GifBitmapWrapperResource(GifBitmapWrapper data) {
+ if (data == null) {
+ throw new NullPointerException("Data must not be null");
+ }
this.data = data;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceDecoder.java
index 1ec8d720..18b198a2 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceDecoder.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.gifbitmap;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceEncoder.java b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceEncoder.java
index 175535f8..ee18ab71 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceEncoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperResourceEncoder.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.gifbitmap;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.ResourceEncoder;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.gif.GifDrawable;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperTransformation.java b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperTransformation.java
index a985b318..791e81bd 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperTransformation.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/GifBitmapWrapperTransformation.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.gifbitmap;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/ImageVideoGifDrawableLoadProvider.java b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/ImageVideoGifDrawableLoadProvider.java
index 56b2ebfa..e084fb52 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/ImageVideoGifDrawableLoadProvider.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gifbitmap/ImageVideoGifDrawableLoadProvider.java
@@ -2,14 +2,14 @@ package com.bumptech.glide.load.resource.gifbitmap;
import android.graphics.Bitmap;
-import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
-import com.bumptech.glide.load.resource.gif.GifDrawable;
-import com.bumptech.glide.provider.DataLoadProvider;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.ResourceEncoder;
+import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.model.ImageVideoWrapper;
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
+import com.bumptech.glide.load.resource.gif.GifDrawable;
+import com.bumptech.glide.provider.DataLoadProvider;
import java.io.File;
import java.io.InputStream;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapBytesTranscoder.java b/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapBytesTranscoder.java
index ef899eaf..01d94407 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapBytesTranscoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapBytesTranscoder.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.transcode;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.bytes.BytesResource;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapToGlideDrawableTranscoder.java b/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapToGlideDrawableTranscoder.java
index 11783990..29343916 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapToGlideDrawableTranscoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/transcode/BitmapToGlideDrawableTranscoder.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.load.resource.transcode;
import android.content.Context;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/transcode/GifBitmapWrapperDrawableTranscoder.java b/library/src/main/java/com/bumptech/glide/load/resource/transcode/GifBitmapWrapperDrawableTranscoder.java
index 39b3a6a3..d226d68d 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/transcode/GifBitmapWrapperDrawableTranscoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/transcode/GifBitmapWrapperDrawableTranscoder.java
@@ -1,6 +1,7 @@
package com.bumptech.glide.load.resource.transcode;
import android.graphics.Bitmap;
+
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/transcode/GlideBitmapDrawableTranscoder.java b/library/src/main/java/com/bumptech/glide/load/resource/transcode/GlideBitmapDrawableTranscoder.java
index 9c7425bc..bdc03df8 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/transcode/GlideBitmapDrawableTranscoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/transcode/GlideBitmapDrawableTranscoder.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.load.resource.transcode;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
diff --git a/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java b/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java
index d4830796..b0b80fa5 100644
--- a/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java
+++ b/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java
@@ -13,6 +13,7 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;
+
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.util.Util;
diff --git a/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java b/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java
index c6ad8bd7..b5e73b6d 100644
--- a/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java
+++ b/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java
@@ -2,6 +2,7 @@ package com.bumptech.glide.manager;
import android.annotation.SuppressLint;
import android.support.v4.app.Fragment;
+
import com.bumptech.glide.RequestManager;
/**
diff --git a/library/src/main/java/com/bumptech/glide/provider/LoadProvider.java b/library/src/main/java/com/bumptech/glide/provider/LoadProvider.java
index 568d0ee5..694ab54b 100644
--- a/library/src/main/java/com/bumptech/glide/provider/LoadProvider.java
+++ b/library/src/main/java/com/bumptech/glide/provider/LoadProvider.java
@@ -1,7 +1,7 @@
package com.bumptech.glide.provider;
-import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import com.bumptech.glide.load.model.ModelLoader;
+import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
/**
* An extension of {@link com.bumptech.glide.provider.DataLoadProvider} that also allows a
diff --git a/library/src/main/java/com/bumptech/glide/request/GenericRequest.java b/library/src/main/java/com/bumptech/glide/request/GenericRequest.java
index 423437cd..7472a02d 100644
--- a/library/src/main/java/com/bumptech/glide/request/GenericRequest.java
+++ b/library/src/main/java/com/bumptech/glide/request/GenericRequest.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.request;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
+
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.Transformation;
@@ -67,7 +68,7 @@ public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallb
private boolean isMemoryCacheable;
private Priority priority;
private Target<R> target;
- private RequestListener<A, R> requestListener;
+ private RequestListener<? super A, R> requestListener;
private float sizeMultiplier;
private Engine engine;
private GlideAnimationFactory<R> animationFactory;
@@ -96,7 +97,7 @@ public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallb
int placeholderResourceId,
Drawable errorDrawable,
int errorResourceId,
- RequestListener<A, R> requestListener,
+ RequestListener<? super A, R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
Transformation<Z> transformation,
@@ -168,7 +169,7 @@ public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallb
int placeholderResourceId,
Drawable errorDrawable,
int errorResourceId,
- RequestListener<A, R> requestListener,
+ RequestListener<? super A, R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
Transformation<Z> transformation,
@@ -181,7 +182,7 @@ public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallb
this.loadProvider = loadProvider;
this.model = model;
this.signature = signature;
- this.context = context;
+ this.context = context.getApplicationContext();
this.priority = priority;
this.target = target;
this.sizeMultiplier = sizeMultiplier;
diff --git a/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeFactory.java b/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeFactory.java
new file mode 100644
index 00000000..5bd3305f
--- /dev/null
+++ b/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeFactory.java
@@ -0,0 +1,72 @@
+package com.bumptech.glide.request.animation;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+
+/**
+ * A factory class that produces a new {@link com.bumptech.glide.request.animation.GlideAnimation} that varies depending
+ * on whether or not the drawable was loaded from the memory cache and whether or not the drawable is the first
+ * image to be set on the target.
+ *
+ * <p>
+ * Resources are usually loaded from the memory cache just before the user can see the view,
+ * for example when the user changes screens or scrolls back and forth in a list. In those cases the user
+ * typically does not expect to see an animation. As a result, when the resource is loaded from the memory
+ * cache this factory produces an {@link com.bumptech.glide.request.animation.NoAnimation}.
+ * </p>
+ *
+ * @param <T> The type of the {@link android.graphics.drawable.Drawable} that will be animated.
+ */
+public class DrawableCrossFadeFactory<T extends Drawable> implements GlideAnimationFactory<T> {
+ private static final int DEFAULT_DURATION_MS = 300;
+ private final ViewAnimationFactory<T> animationFactory;
+ private final int duration;
+ private DrawableCrossFadeViewAnimation<T> animation;
+
+ public DrawableCrossFadeFactory() {
+ this(DEFAULT_DURATION_MS);
+ }
+
+ public DrawableCrossFadeFactory(int duration) {
+ this(new ViewAnimationFactory<T>(new DefaultAnimationFactory()), duration);
+ }
+
+ public DrawableCrossFadeFactory(Context context, int defaultAnimationId, int duration) {
+ this(new ViewAnimationFactory<T>(context, defaultAnimationId), duration);
+ }
+
+ public DrawableCrossFadeFactory(Animation defaultAnimation, int duration) {
+ this(new ViewAnimationFactory<T>(defaultAnimation), duration);
+ }
+
+ DrawableCrossFadeFactory(ViewAnimationFactory<T> animationFactory, int duration) {
+ this.animationFactory = animationFactory;
+ this.duration = duration;
+ }
+
+ @Override
+ public GlideAnimation<T> build(boolean isFromMemoryCache, boolean isFirstResource) {
+ if (isFromMemoryCache) {
+ return NoAnimation.get();
+ }
+
+ if (animation == null) {
+ GlideAnimation<T> defaultAnimation = animationFactory.build(false, isFirstResource);
+ animation = new DrawableCrossFadeViewAnimation<T>(defaultAnimation, duration);
+ }
+
+ return animation;
+ }
+
+ private static class DefaultAnimationFactory implements ViewAnimation.AnimationFactory {
+
+ @Override
+ public Animation build() {
+ AlphaAnimation animation = new AlphaAnimation(0f, 1f);
+ animation.setDuration(DEFAULT_DURATION_MS / 2);
+ return animation;
+ }
+ }
+}
diff --git a/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java b/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java
index bf2d3eea..a721aa1c 100644
--- a/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java
+++ b/library/src/main/java/com/bumptech/glide/request/animation/DrawableCrossFadeViewAnimation.java
@@ -1,10 +1,7 @@
package com.bumptech.glide.request.animation;
-import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
/**
* A cross fade {@link GlideAnimation} for {@link android.graphics.drawable.Drawable}s
@@ -15,65 +12,10 @@ import android.view.animation.Animation;
* @param <T> The type of the {@link android.graphics.drawable.Drawable} that will be animated.
*/
public class DrawableCrossFadeViewAnimation<T extends Drawable> implements GlideAnimation<T> {
- // 150 ms.
- public static final int DEFAULT_DURATION = 300;
private final GlideAnimation<T> defaultAnimation;
private final int duration;
/**
- * A factory class that produces a new {@link GlideAnimation} that varies depending
- * on whether or not the drawable was loaded from the memory cache and whether or not the drawable is the first
- * image to be set on the target.
- *
- * <p>
- * Resources are usually loaded from the memory cache just before the user can see the view,
- * for example when the user changes screens or scrolls back and forth in a list. In those cases the user
- * typically does not expect to see an animation. As a result, when the resource is loaded from the memory
- * cache this factory producdes an {@link NoAnimation}.
- * </p>
- */
- public static class DrawableCrossFadeFactory<T extends Drawable> implements GlideAnimationFactory<T> {
- private final ViewAnimation.ViewAnimationFactory<T> animationFactory;
- private final int duration;
- private DrawableCrossFadeViewAnimation<T> animation;
-
- public DrawableCrossFadeFactory() {
- this(DEFAULT_DURATION);
- }
-
- public DrawableCrossFadeFactory(int duration) {
- this(new ViewAnimation.ViewAnimationFactory<T>(new DefaultAnimationFactory()), duration);
- }
-
- public DrawableCrossFadeFactory(Context context, int defaultAnimationId, int duration) {
- this(new ViewAnimation.ViewAnimationFactory<T>(context, defaultAnimationId), duration);
- }
-
- public DrawableCrossFadeFactory(Animation defaultAnimation, int duration) {
- this(new ViewAnimation.ViewAnimationFactory<T>(defaultAnimation), duration);
- }
-
- DrawableCrossFadeFactory(ViewAnimation.ViewAnimationFactory<T> animationFactory, int duration) {
- this.animationFactory = animationFactory;
- this.duration = duration;
- }
-
- @Override
- public GlideAnimation<T> build(boolean isFromMemoryCache, boolean isFirstResource) {
- if (isFromMemoryCache) {
- return NoAnimation.get();
- }
-
- if (animation == null) {
- GlideAnimation<T> defaultAnimation = animationFactory.build(false, isFirstResource);
- animation = new DrawableCrossFadeViewAnimation<T>(defaultAnimation, duration);
- }
-
- return animation;
- }
- }
-
- /**
* Constructor that takes a default animation and a duration in milliseconds that the cross fade animation should
* last.
* @param duration The duration that the cross fade animation should run if there is something to cross fade from
@@ -111,14 +53,4 @@ public class DrawableCrossFadeViewAnimation<T extends Drawable> implements Glide
return false;
}
}
-
- private static class DefaultAnimationFactory implements ViewAnimation.AnimationFactory {
-
- @Override
- public Animation build() {
- AlphaAnimation animation = new AlphaAnimation(0f, 1f);
- animation.setDuration(DEFAULT_DURATION / 2);
- return animation;
- }
- }
}
diff --git a/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java b/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java
index aeea7187..7f62719d 100644
--- a/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java
+++ b/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimation.java
@@ -1,9 +1,7 @@
package com.bumptech.glide.request.animation;
-import android.content.Context;
import android.view.View;
import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
/**
* A {@link com.bumptech.glide.request.animation.GlideAnimation GlideAnimation} that can apply a
@@ -45,76 +43,6 @@ public class ViewAnimation<R> implements GlideAnimation<R> {
return false;
}
- /**
- * A {@link com.bumptech.glide.request.animation.GlideAnimationFactory} that produces ViewAnimations.
- */
- public static class ViewAnimationFactory<R> implements GlideAnimationFactory<R> {
- private final AnimationFactory animationFactory;
- private GlideAnimation<R> glideAnimation;
-
- public ViewAnimationFactory(Animation animation) {
- this(new ConcreteAnimationFactory(animation));
- }
-
- public ViewAnimationFactory(Context context, int animationId) {
- this(new ResourceAnimationFactory(context, animationId));
- }
-
- ViewAnimationFactory(AnimationFactory animationFactory) {
- this.animationFactory = animationFactory;
- }
-
- /**
- * Returns a new {@link com.bumptech.glide.request.animation.GlideAnimation} for the given arguments. If
- * isFromMemoryCache is {@code true} or isFirstImage is {@code false}, returns a
- * {@link com.bumptech.glide.request.animation.NoAnimation} and otherwise returns a new
- * {@link com.bumptech.glide.request.animation.ViewAnimation}.
- *
- * @param isFromMemoryCache {@inheritDoc}
- * @param isFirstResource {@inheritDoc}
- */
- @Override
- public GlideAnimation<R> build(boolean isFromMemoryCache, boolean isFirstResource) {
- if (isFromMemoryCache || !isFirstResource) {
- return NoAnimation.get();
- }
-
- if (glideAnimation == null) {
- glideAnimation = new ViewAnimation<R>(animationFactory);
- }
-
- return glideAnimation;
- }
- }
-
- private static class ConcreteAnimationFactory implements AnimationFactory {
- private final Animation animation;
-
- public ConcreteAnimationFactory(Animation animation) {
- this.animation = animation;
- }
-
- @Override
- public Animation build() {
- return animation;
- }
- }
-
- private static class ResourceAnimationFactory implements AnimationFactory {
- private final Context context;
- private final int animationId;
-
- public ResourceAnimationFactory(Context context, int animationId) {
- this.context = context.getApplicationContext();
- this.animationId = animationId;
- }
-
- @Override
- public Animation build() {
- return AnimationUtils.loadAnimation(context, animationId);
- }
- }
-
interface AnimationFactory {
Animation build();
}
diff --git a/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimationFactory.java b/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimationFactory.java
new file mode 100644
index 00000000..df2761aa
--- /dev/null
+++ b/library/src/main/java/com/bumptech/glide/request/animation/ViewAnimationFactory.java
@@ -0,0 +1,78 @@
+package com.bumptech.glide.request.animation;
+
+import android.content.Context;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+/**
+ * A {@link com.bumptech.glide.request.animation.GlideAnimationFactory} that produces
+ * {@link com.bumptech.glide.request.animation.ViewAnimation}s.
+ *
+ * @param <R> The type of the resource displayed in the view that is animated
+ */
+public class ViewAnimationFactory<R> implements GlideAnimationFactory<R> {
+ private final ViewAnimation.AnimationFactory animationFactory;
+ private GlideAnimation<R> glideAnimation;
+
+ public ViewAnimationFactory(Animation animation) {
+ this(new ConcreteAnimationFactory(animation));
+ }
+
+ public ViewAnimationFactory(Context context, int animationId) {
+ this(new ResourceAnimationFactory(context, animationId));
+ }
+
+ ViewAnimationFactory(ViewAnimation.AnimationFactory animationFactory) {
+ this.animationFactory = animationFactory;
+ }
+
+ /**
+ * Returns a new {@link com.bumptech.glide.request.animation.GlideAnimation} for the given arguments. If
+ * isFromMemoryCache is {@code true} or isFirstImage is {@code false}, returns a
+ * {@link com.bumptech.glide.request.animation.NoAnimation} and otherwise returns a new
+ * {@link com.bumptech.glide.request.animation.ViewAnimation}.
+ *
+ * @param isFromMemoryCache {@inheritDoc}
+ * @param isFirstResource {@inheritDoc}
+ */
+ @Override
+ public GlideAnimation<R> build(boolean isFromMemoryCache, boolean isFirstResource) {
+ if (isFromMemoryCache || !isFirstResource) {
+ return NoAnimation.get();
+ }
+
+ if (glideAnimation == null) {
+ glideAnimation = new ViewAnimation<R>(animationFactory);
+ }
+
+ return glideAnimation;
+ }
+
+ private static class ConcreteAnimationFactory implements ViewAnimation.AnimationFactory {
+ private final Animation animation;
+
+ public ConcreteAnimationFactory(Animation animation) {
+ this.animation = animation;
+ }
+
+ @Override
+ public Animation build() {
+ return animation;
+ }
+ }
+
+ private static class ResourceAnimationFactory implements ViewAnimation.AnimationFactory {
+ private final Context context;
+ private final int animationId;
+
+ public ResourceAnimationFactory(Context context, int animationId) {
+ this.context = context.getApplicationContext();
+ this.animationId = animationId;
+ }
+
+ @Override
+ public Animation build() {
+ return AnimationUtils.loadAnimation(context, animationId);
+ }
+ }
+}
diff --git a/library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimation.java b/library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimation.java
index 9c664df4..6b42e81f 100644
--- a/library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimation.java
+++ b/library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimation.java
@@ -54,34 +54,4 @@ public class ViewPropertyAnimation<R> implements GlideAnimation<R> {
void animate(View view);
}
- /**
- * A {@link com.bumptech.glide.request.animation.GlideAnimationFactory} that produces ViewPropertyAnimations.
- */
- public static class ViewPropertyAnimationFactory<R> implements GlideAnimationFactory<R> {
- private final Animator animator;
- private ViewPropertyAnimation<R> animation;
-
- public ViewPropertyAnimationFactory(Animator animator) {
- this.animator = animator;
- }
-
- /**
- * Returns a new {@link com.bumptech.glide.request.animation.GlideAnimation} for the given arguments. If
- * isMemoryCache is {@code true} or isFirstImage is {@code false}, returns a
- * {@link com.bumptech.glide.request.animation.NoAnimation} and otherwise returns a new
- * {@link com.bumptech.glide.request.animation.ViewPropertyAnimation} for the
- * {@link com.bumptech.glide.request.animation.ViewPropertyAnimation.Animator} provided in the constructor.
- */
- @Override
- public GlideAnimation<R> build(boolean isFromMemoryCache, boolean isFirstResource) {
- if (isFromMemoryCache || !isFirstResource) {
- return NoAnimation.get();
- }
- if (animation == null) {
- animation = new ViewPropertyAnimation<R>(animator);
- }
-
- return animation;
- }
- }
}
diff --git a/library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimationFactory.java b/library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimationFactory.java
new file mode 100644
index 00000000..f8c5002f
--- /dev/null
+++ b/library/src/main/java/com/bumptech/glide/request/animation/ViewPropertyAnimationFactory.java
@@ -0,0 +1,34 @@
+package com.bumptech.glide.request.animation;
+
+/**
+ * A {@link GlideAnimationFactory} that produces ViewPropertyAnimations.
+ *
+ * @param <R> The type of the resource displayed in the view that is animated
+ */
+public class ViewPropertyAnimationFactory<R> implements GlideAnimationFactory<R> {
+ private final ViewPropertyAnimation.Animator animator;
+ private ViewPropertyAnimation<R> animation;
+
+ public ViewPropertyAnimationFactory(ViewPropertyAnimation.Animator animator) {
+ this.animator = animator;
+ }
+
+ /**
+ * Returns a new {@link GlideAnimation} for the given arguments. If
+ * isMemoryCache is {@code true} or isFirstImage is {@code false}, returns a
+ * {@link NoAnimation} and otherwise returns a new
+ * {@link ViewPropertyAnimation} for the
+ * {@link com.bumptech.glide.request.animation.ViewPropertyAnimation.Animator} provided in the constructor.
+ */
+ @Override
+ public GlideAnimation<R> build(boolean isFromMemoryCache, boolean isFirstResource) {
+ if (isFromMemoryCache || !isFirstResource) {
+ return NoAnimation.get();
+ }
+ if (animation == null) {
+ animation = new ViewPropertyAnimation<R>(animator);
+ }
+
+ return animation;
+ }
+}
diff --git a/library/src/main/java/com/bumptech/glide/request/target/ImageViewTargetFactory.java b/library/src/main/java/com/bumptech/glide/request/target/ImageViewTargetFactory.java
index 24790c74..97e84f37 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/ImageViewTargetFactory.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/ImageViewTargetFactory.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.request.target;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
+
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
/**
diff --git a/library/src/main/java/com/bumptech/glide/request/target/PreloadTarget.java b/library/src/main/java/com/bumptech/glide/request/target/PreloadTarget.java
index 8dfbe600..a8a9b5a2 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/PreloadTarget.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/PreloadTarget.java
@@ -14,8 +14,8 @@ public final class PreloadTarget<Z> extends SimpleTarget<Z> {
/**
* Returns a PreloadTarget.
*
- * @param width The width of the desired resourece.
- * @param height The height of the desired resource.
+ * @param width The width in pixels of the desired resource.
+ * @param height The height in pixels of the desired resource.
* @param <Z> The type of the desired resource.
*/
public static <Z> PreloadTarget<Z> obtain(int width, int height) {
diff --git a/library/src/main/java/com/bumptech/glide/request/target/SimpleTarget.java b/library/src/main/java/com/bumptech/glide/request/target/SimpleTarget.java
index 78522c32..cdbc9a49 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/SimpleTarget.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/SimpleTarget.java
@@ -44,8 +44,8 @@ public abstract class SimpleTarget<Z> extends BaseTarget<Z> {
/**
* Constructor for the target that takes the desired dimensions of the decoded and/or transformed resource.
*
- * @param width The desired width of the resource.
- * @param height The desired height of the resource.
+ * @param width The width in pixels of the desired resource.
+ * @param height The height in pixels of the desired resource.
*/
public SimpleTarget(int width, int height) {
this.width = width;
diff --git a/library/src/main/java/com/bumptech/glide/request/target/SizeReadyCallback.java b/library/src/main/java/com/bumptech/glide/request/target/SizeReadyCallback.java
index eb382cd6..22b41180 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/SizeReadyCallback.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/SizeReadyCallback.java
@@ -8,8 +8,8 @@ public interface SizeReadyCallback {
/**
* A callback called on the main thread.
*
- * @param width The width of the target.
- * @param height The height of the target.
+ * @param width The width in pixels of the target.
+ * @param height The height in pixels of the target.
*/
void onSizeReady(int width, int height);
}
diff --git a/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java b/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
index cff57f70..dcf7f5d0 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
@@ -7,6 +7,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
+
import com.bumptech.glide.request.Request;
import java.lang.ref.WeakReference;
diff --git a/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java b/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java
index 667b3dff..1ea2ca10 100644
--- a/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java
+++ b/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java
@@ -3,6 +3,7 @@ package com.bumptech.glide.signature;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+
import com.bumptech.glide.load.Key;
import java.util.UUID;
diff --git a/library/src/main/java/com/bumptech/glide/signature/MediaStoreSignature.java b/library/src/main/java/com/bumptech/glide/signature/MediaStoreSignature.java
index 4774a69b..dbeb876d 100644
--- a/library/src/main/java/com/bumptech/glide/signature/MediaStoreSignature.java
+++ b/library/src/main/java/com/bumptech/glide/signature/MediaStoreSignature.java
@@ -15,6 +15,18 @@ public class MediaStoreSignature implements Key {
private final long dateModified;
private final int orientation;
+ /**
+ * Constructor for {@link com.bumptech.glide.signature.MediaStoreSignature}.
+ *
+ * @param mimeType The mime type of the media store media. Ok to default to empty string "". See
+ * {@link android.provider.MediaStore.Images.ImageColumns#MIME_TYPE} or
+ * {@link android.provider.MediaStore.Video.VideoColumns#MIME_TYPE}.
+ * @param dateModified The date modified time of the media store media. Ok to default to 0. See
+ * {@link android.provider.MediaStore.Images.ImageColumns#DATE_MODIFIED} or
+ * {@link android.provider.MediaStore.Video.VideoColumns#DATE_MODIFIED}.
+ * @param orientation The orientation of the media store media. Ok to default to 0. See
+ * {@link android.provider.MediaStore.Images.ImageColumns#ORIENTATION}.
+ */
public MediaStoreSignature(String mimeType, long dateModified, int orientation) {
this.mimeType = mimeType;
this.dateModified = dateModified;
diff --git a/library/src/main/java/com/bumptech/glide/util/ExceptionCatchingInputStream.java b/library/src/main/java/com/bumptech/glide/util/ExceptionCatchingInputStream.java
index 12df71c3..344a2894 100644
--- a/library/src/main/java/com/bumptech/glide/util/ExceptionCatchingInputStream.java
+++ b/library/src/main/java/com/bumptech/glide/util/ExceptionCatchingInputStream.java
@@ -1,5 +1,7 @@
package com.bumptech.glide.util;
+import com.bumptech.glide.load.resource.bitmap.RecyclableBufferedInputStream;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.Queue;
@@ -15,10 +17,10 @@ public class ExceptionCatchingInputStream extends InputStream {
private static final Queue<ExceptionCatchingInputStream> QUEUE = Util.createQueue(0);
- private InputStream wrapped;
+ private RecyclableBufferedInputStream wrapped;
private IOException exception;
- public static ExceptionCatchingInputStream obtain(InputStream toWrap) {
+ public static ExceptionCatchingInputStream obtain(RecyclableBufferedInputStream toWrap) {
ExceptionCatchingInputStream result;
synchronized (QUEUE) {
result = QUEUE.poll();
@@ -41,7 +43,7 @@ public class ExceptionCatchingInputStream extends InputStream {
// Do nothing.
}
- void setInputStream(InputStream toWrap) {
+ void setInputStream(RecyclableBufferedInputStream toWrap) {
wrapped = toWrap;
}
@@ -118,6 +120,10 @@ public class ExceptionCatchingInputStream extends InputStream {
return result;
}
+ public void fixMarkLimit() {
+ wrapped.fixMarkLimit();
+ }
+
public IOException getException() {
return exception;
}
diff --git a/library/src/main/java/com/bumptech/glide/util/Util.java b/library/src/main/java/com/bumptech/glide/util/Util.java
index 5d03cfdd..cc0743fe 100644
--- a/library/src/main/java/com/bumptech/glide/util/Util.java
+++ b/library/src/main/java/com/bumptech/glide/util/Util.java
@@ -53,7 +53,8 @@ public final class Util {
*
* @see #getBitmapByteSize(android.graphics.Bitmap)
*
- * @deprecated
+ * @deprecated Use {@link #getBitmapByteSize(android.graphics.Bitmap)} instead. Scheduled to be removed in Glide
+ * 4.0.
*/
@Deprecated
public static int getSize(Bitmap bitmap) {
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index 8e11f324..00000000
--- a/settings.gradle
+++ /dev/null
@@ -1,13 +0,0 @@
-include ':library'
-include ':glide'
-include ':third_party:gif_decoder'
-include ':third_party:disklrucache'
-include ':third_party:gif_encoder'
-include ':samples:flickr'
-include ':samples:giphy'
-include ':samples:svg'
-include ':integration'
-include ':integration:volley'
-include ':integration:okhttp'
-
-rootProject.name = 'glide-parent'
diff --git a/static/glide_logo.png b/static/glide_logo.png
deleted file mode 100644
index f9f4d799..00000000
--- a/static/glide_logo.png
+++ /dev/null
Binary files differ
diff --git a/testutil/src/main/java/com/bumptech/glide/testutil/TestResourceUtil.java b/testutil/src/main/java/com/bumptech/glide/testutil/TestResourceUtil.java
new file mode 100644
index 00000000..e523b67d
--- /dev/null
+++ b/testutil/src/main/java/com/bumptech/glide/testutil/TestResourceUtil.java
@@ -0,0 +1,23 @@
+package com.bumptech.glide.testutil;
+
+import java.io.InputStream;
+
+/**
+ * Test only utility for opening resources in androidTest/resources.
+ */
+public final class TestResourceUtil {
+ private TestResourceUtil() {
+ // Utility class
+ }
+
+ /**
+ * Returns an InputStream for the given test class and sub-path.
+ *
+ * @param testClass A Junit test class.
+ * @param subPath The sub-path under androidTest/resources where the desired resource is located.
+ * Should not be prefixed with a '/'
+ */
+ public static InputStream openResource(Class testClass, String subPath) {
+ return testClass.getResourceAsStream("/" + subPath);
+ }
+}
diff --git a/testutil/src/main/java/com/bumptech/glide/testutil/TestUtil.java b/testutil/src/main/java/com/bumptech/glide/testutil/TestUtil.java
new file mode 100644
index 00000000..0ad40e0e
--- /dev/null
+++ b/testutil/src/main/java/com/bumptech/glide/testutil/TestUtil.java
@@ -0,0 +1,37 @@
+package com.bumptech.glide.testutil;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Shared utility classes for tests.
+ */
+public final class TestUtil {
+ private TestUtil() {
+ // Utility class.
+ }
+
+ public static byte[] resourceToBytes(Class testClass, String resourceName) throws IOException {
+ return isToBytes(TestResourceUtil.openResource(testClass, resourceName));
+ }
+
+ public static byte[] isToBytes(InputStream is) throws IOException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int read;
+ try {
+ while ((read = is.read(buffer)) != -1) {
+ os.write(buffer, 0, read);
+ }
+ } finally {
+ is.close();
+ }
+ return os.toByteArray();
+ }
+
+ public static String isToString(InputStream is) throws IOException {
+ return new String(isToBytes(is));
+ }
+
+}
diff --git a/third_party/disklrucache/README.md b/third_party/disklrucache/README.md
index a02e39cd..5f27ca26 100644
--- a/third_party/disklrucache/README.md
+++ b/third_party/disklrucache/README.md
@@ -43,22 +43,6 @@ appropriately.
*Note: This implementation specifically targets Android compatibility.*
-
-
-Obtaining
-=========
-
-If you are a Maven user you can also add this library as a dependency. Add the
-following to your `pom.xml`:
-
-```xml
-<dependency>
- <groupId>com.bumptech.glide</groupId>
- <artifactId>disklrucache</artifactId>
- <version>(insert latest version)</version>
-</dependency>
-```
-
License
=======
diff --git a/third_party/disklrucache/README.third_party b/third_party/disklrucache/README.third_party
index 9ffe3cbd..88189ae3 100644
--- a/third_party/disklrucache/README.third_party
+++ b/third_party/disklrucache/README.third_party
@@ -1,5 +1,5 @@
-URL: https://github.com/judds/DiskLruCache/tarball/b9ed9f4501d90e59128203b62e14b4cad91b6cdd
-Version: b9ed9f4501d90e59128203b62e14b4cad91b6cdd
+URL: https://github.com/JakeWharton/DiskLruCache/tarball/7a1ecbd38d2ad0873fb843e911d60235b7434acb
+Version: 7a1ecbd38d2ad0873fb843e911d60235b7434acb
License: Apache 2.0
License File: LICENSE
@@ -7,4 +7,4 @@ Description:
Java implementation of a Disk-based LRU cache which specifically targets Android compatibility.
Local Modifications:
-Exposed File objects directly to gets, removed test sources.
+Exposed File objects directly to gets, removed key validation, removed test sources.
diff --git a/third_party/disklrucache/build.gradle b/third_party/disklrucache/build.gradle
deleted file mode 100644
index 0e876389..00000000
--- a/third_party/disklrucache/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-apply plugin: 'java'
-apply plugin: 'checkstyle'
-
-repositories {
- jcenter()
-}
-
-checkstyle {
- configFile = new File(projectDir, 'checkstyle.xml')
-}
-
-dependencies {
- testCompile 'junit:junit:4.10'
- testCompile 'commons-io:commons-io:2.1'
- testCompile 'org.easytesting:fest-assert-core:2.0M10'
-}
diff --git a/third_party/disklrucache/checkstyle.xml b/third_party/disklrucache/checkstyle.xml
deleted file mode 100644
index de84efb9..00000000
--- a/third_party/disklrucache/checkstyle.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE module PUBLIC
- "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
- "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
-
-<module name="Checker">
- <module name="NewlineAtEndOfFile"/>
- <module name="FileLength"/>
- <module name="FileTabCharacter"/>
-
- <!-- Trailing spaces -->
- <module name="RegexpSingleline">
- <property name="format" value="\s+$"/>
- <property name="message" value="Line has trailing spaces."/>
- </module>
-
- <!-- Space after 'for' and 'if' -->
- <module name="RegexpSingleline">
- <property name="format" value="^\s*(for|if)\b[^ ]"/>
- <property name="message" value="Space needed before opening parenthesis."/>
- </module>
-
- <!-- For each spacing -->
- <module name="RegexpSingleline">
- <property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
- <property name="message" value="Space needed around ':' character."/>
- </module>
-
- <module name="TreeWalker">
- <!-- Checks for Javadoc comments. -->
- <!-- See http://checkstyle.sf.net/config_javadoc.html -->
- <!--module name="JavadocMethod"/-->
- <!--module name="JavadocType"/-->
- <!--module name="JavadocVariable"/-->
- <module name="JavadocStyle"/>
-
-
- <!-- Checks for Naming Conventions. -->
- <!-- See http://checkstyle.sf.net/config_naming.html -->
- <!--<module name="ConstantName"/>-->
- <module name="LocalFinalVariableName"/>
- <module name="LocalVariableName"/>
- <module name="MemberName"/>
- <module name="MethodName"/>
- <module name="PackageName"/>
- <module name="ParameterName"/>
- <module name="StaticVariableName"/>
- <module name="TypeName"/>
-
-
- <!-- Checks for imports -->
- <!-- See http://checkstyle.sf.net/config_import.html -->
- <module name="AvoidStarImport"/>
- <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
- <module name="RedundantImport"/>
- <module name="UnusedImports"/>
-
-
- <!-- Checks for Size Violations. -->
- <!-- See http://checkstyle.sf.net/config_sizes.html -->
- <module name="LineLength">
- <property name="max" value="100"/>
- </module>
- <module name="MethodLength"/>
- <module name="ParameterNumber"/>
-
-
- <!-- Checks for whitespace -->
- <!-- See http://checkstyle.sf.net/config_whitespace.html -->
- <module name="GenericWhitespace"/>
- <!--<module name="EmptyForIteratorPad"/>-->
- <module name="MethodParamPad"/>
- <!--<module name="NoWhitespaceAfter"/>-->
- <!--<module name="NoWhitespaceBefore"/>-->
- <module name="OperatorWrap"/>
- <module name="ParenPad"/>
- <module name="TypecastParenPad"/>
- <module name="WhitespaceAfter"/>
- <module name="WhitespaceAround"/>
-
-
- <!-- Modifier Checks -->
- <!-- See http://checkstyle.sf.net/config_modifiers.html -->
- <module name="ModifierOrder"/>
- <module name="RedundantModifier"/>
-
-
- <!-- Checks for blocks. You know, those {}'s -->
- <!-- See http://checkstyle.sf.net/config_blocks.html -->
- <module name="AvoidNestedBlocks"/>
- <!--module name="EmptyBlock"/-->
- <module name="LeftCurly"/>
- <!--<module name="NeedBraces"/>-->
- <module name="RightCurly"/>
-
-
- <!-- Checks for common coding problems -->
- <!-- See http://checkstyle.sf.net/config_coding.html -->
- <!--module name="AvoidInlineConditionals"/-->
- <module name="CovariantEquals"/>
- <module name="EmptyStatement"/>
- <!--<module name="EqualsAvoidNull"/>-->
- <module name="EqualsHashCode"/>
- <!--module name="HiddenField"/-->
- <module name="IllegalInstantiation"/>
- <!--module name="InnerAssignment"/-->
- <!--module name="MagicNumber"/-->
- <!--module name="MissingSwitchDefault"/-->
- <module name="RedundantThrows"/>
- <module name="SimplifyBooleanExpression"/>
- <module name="SimplifyBooleanReturn"/>
-
- <!-- Checks for class design -->
- <!-- See http://checkstyle.sf.net/config_design.html -->
- <!--module name="DesignForExtension"/-->
- <!--<module name="FinalClass"/>-->
- <module name="HideUtilityClassConstructor"/>
- <module name="InterfaceIsType"/>
- <!--module name="VisibilityModifier"/-->
-
-
- <!-- Miscellaneous other checks. -->
- <!-- See http://checkstyle.sf.net/config_misc.html -->
- <module name="ArrayTypeStyle"/>
- <!--module name="FinalParameters"/-->
- <!--module name="TodoComment"/-->
- <module name="UpperEll"/>
- </module>
-</module>
diff --git a/third_party/disklrucache/gradle/wrapper/gradle-wrapper.jar b/third_party/disklrucache/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 0087cd3b..00000000
--- a/third_party/disklrucache/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/third_party/disklrucache/gradle/wrapper/gradle-wrapper.properties b/third_party/disklrucache/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index d9c5a25c..00000000
--- a/third_party/disklrucache/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Sat Jun 28 20:49:51 PDT 2014
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-all.zip
diff --git a/third_party/disklrucache/gradlew b/third_party/disklrucache/gradlew
deleted file mode 100755
index 91a7e269..00000000
--- a/third_party/disklrucache/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/DiskLruCache.java b/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/DiskLruCache.java
index a6cbd78d..7fb4479e 100644
--- a/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/DiskLruCache.java
+++ b/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/DiskLruCache.java
@@ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit;
/**
* A cache that uses a bounded amount of space on a filesystem. Each cache
* entry has a string key and a fixed number of values. Each key must match
- * the regex <strong>[a-z0-9_-]{1,64}</strong>. Values are byte sequences,
+ * the regex <strong>[a-z0-9_-]{1,120}</strong>. Values are byte sequences,
* accessible as streams or files. Each value must be between {@code 0} and
* {@code Integer.MAX_VALUE} bytes in length.
*
@@ -219,8 +219,6 @@ public final class DiskLruCache implements Closeable {
try {
cache.readJournal();
cache.processJournal();
- cache.journalWriter = new BufferedWriter(
- new OutputStreamWriter(new FileOutputStream(cache.journalFile, true), Util.US_ASCII));
return cache;
} catch (IOException journalIsCorrupt) {
System.out
@@ -267,6 +265,14 @@ public final class DiskLruCache implements Closeable {
}
}
redundantOpCount = lineCount - lruEntries.size();
+
+ // If we ended on a truncated line, rebuild the journal before appending to it.
+ if (reader.hasUnterminatedLine()) {
+ rebuildJournal();
+ } else {
+ journalWriter = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(journalFile, true), Util.US_ASCII));
+ }
} finally {
Util.closeQuietly(reader);
}
diff --git a/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/StrictLineReader.java b/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/StrictLineReader.java
index 96b68608..11135db0 100644
--- a/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/StrictLineReader.java
+++ b/third_party/disklrucache/src/main/java/com/bumptech/glide/disklrucache/StrictLineReader.java
@@ -176,6 +176,10 @@ class StrictLineReader implements Closeable {
}
}
+ public boolean hasUnterminatedLine() {
+ return end == -1;
+ }
+
/**
* Reads new input data into the buffer. Call only with pos == end or end == -1,
* depending on the desired outcome if the function throws.
diff --git a/third_party/gif_decoder/build.gradle b/third_party/gif_decoder/build.gradle
deleted file mode 100644
index 8834279f..00000000
--- a/third_party/gif_decoder/build.gradle
+++ /dev/null
@@ -1,22 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: 'robolectric'
-
-dependencies {
- androidTestCompile 'com.android.support:support-v4:19.1.0'
- androidTestCompile 'org.hamcrest:hamcrest-core:1.3'
- androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
- androidTestCompile 'junit:junit:4.11'
- androidTestCompile 'org.mockito:mockito-all:1.9.5'
- androidTestCompile 'org.robolectric:robolectric:2.4-SNAPSHOT'
-}
-
-android {
- compileSdkVersion 19
- buildToolsVersion '19.1.0'
-
- defaultConfig {
- applicationId 'com.bumptech.glide.gifdecoder'
- minSdkVersion 10
- targetSdkVersion 19
- }
-}
diff --git a/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifDecoder.java b/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifDecoder.java
index 92dc3bfc..c4b4281d 100644
--- a/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifDecoder.java
+++ b/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifDecoder.java
@@ -98,6 +98,11 @@ public class GifDecoder {
private static final int INITIAL_FRAME_POINTER = -1;
+ // We can't tell if a gif has transparency to decode a partial frame on top of a previous frame, or if the final
+ // frame will actually have transparent pixels, so we must always use a format that supports transparency. We can't
+ // use ARGB_4444 because of framework issues drawing onto ARGB_4444 Bitmaps using Canvas.
+ private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
+
// Global File Header values and parsing flags.
// Active color table.
private int[] act;
@@ -123,7 +128,6 @@ public class GifDecoder {
private BitmapProvider bitmapProvider;
private Bitmap previousImage;
private boolean savePrevious;
- private Bitmap.Config config;
private int status;
/**
@@ -135,8 +139,8 @@ public class GifDecoder {
* Returns an {@link Bitmap} with exactly the given dimensions and config, or null if no such {@link Bitmap}
* could be obtained.
*
- * @param width The width of the desired {@link android.graphics.Bitmap}.
- * @param height The height of the desired {@link android.graphics.Bitmap}.
+ * @param width The width in pixels of the desired {@link android.graphics.Bitmap}.
+ * @param height The height in pixels of the desired {@link android.graphics.Bitmap}.
* @param config The {@link android.graphics.Bitmap.Config} of the desired {@link android.graphics.Bitmap}.
*/
public Bitmap obtain(int width, int height, Bitmap.Config config);
@@ -164,10 +168,6 @@ public class GifDecoder {
return data;
}
- public void setPreferredConfig(Bitmap.Config config) {
- this.config = config;
- }
-
/**
* Returns the current status of the decoder.
*
@@ -202,7 +202,7 @@ public class GifDecoder {
}
/**
- * Gets display duration for the upcoming frame.
+ * Gets display duration for the upcoming frame in ms.
*/
public int getNextDelay() {
if (header.frameCount <= 0 || framePointer < 0) {
@@ -248,46 +248,59 @@ public class GifDecoder {
*
* @return Bitmap representation of frame.
*/
- public Bitmap getNextFrame() {
+ public synchronized Bitmap getNextFrame() {
if (header.frameCount <= 0 || framePointer < 0) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "unable to decode frame, frameCount=" + header.frameCount + " framePointer=" + framePointer);
+ }
status = STATUS_FORMAT_ERROR;
}
if (status == STATUS_FORMAT_ERROR || status == STATUS_OPEN_ERROR) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Unable to decode frame, status=" + status);
+ }
return null;
}
status = STATUS_OK;
- GifFrame frame = header.frames.get(framePointer);
+ GifFrame currentFrame = header.frames.get(framePointer);
+ GifFrame previousFrame = null;
+ int previousIndex = framePointer - 1;
+ if (previousIndex >= 0) {
+ previousFrame = header.frames.get(previousIndex);
+ }
// Set the appropriate color table.
- if (frame.lct == null) {
+ if (currentFrame.lct == null) {
act = header.gct;
} else {
- act = frame.lct;
- if (header.bgIndex == frame.transIndex) {
+ act = currentFrame.lct;
+ if (header.bgIndex == currentFrame.transIndex) {
header.bgColor = 0;
}
}
int save = 0;
- if (frame.transparency) {
- save = act[frame.transIndex];
+ if (currentFrame.transparency) {
+ save = act[currentFrame.transIndex];
// Set transparent color if specified.
- act[frame.transIndex] = 0;
+ act[currentFrame.transIndex] = 0;
}
if (act == null) {
- Log.w(TAG, "No Valid Color Table");
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "No Valid Color Table");
+ }
// No color table defined.
status = STATUS_FORMAT_ERROR;
return null;
}
// Transfer pixel data to image.
- Bitmap result = setPixels(framePointer);
+ Bitmap result = setPixels(currentFrame, previousFrame);
// Reset the transparent pixel in the color table
- if (frame.transparency) {
- act[frame.transIndex] = save;
+ if (currentFrame.transparency) {
+ act[currentFrame.transIndex] = save;
}
return result;
@@ -408,13 +421,8 @@ public class GifDecoder {
/**
* Creates new frame image from current data (and previous frames as specified by their disposition codes).
*/
- private Bitmap setPixels(int frameIndex) {
- GifFrame currentFrame = header.frames.get(frameIndex);
- GifFrame previousFrame = null;
- int previousIndex = frameIndex - 1;
- if (previousIndex >= 0) {
- previousFrame = header.frames.get(previousIndex);
- }
+ private Bitmap setPixels(GifFrame currentFrame, GifFrame previousFrame) {
+
int width = header.width;
int height = header.height;
@@ -676,21 +684,10 @@ public class GifDecoder {
return n;
}
- private Bitmap.Config getPreferredConfig() {
- // We can't tell if a gif has transparency to decode a partial frame on top of a previous frame, or if the final
- // frame will actually have transparent pixels, so we must always use a format that supports transparency.
- if (config == Bitmap.Config.RGB_565 || config == Bitmap.Config.ARGB_4444) {
- return Bitmap.Config.ARGB_4444;
- } else {
- return Bitmap.Config.ARGB_8888;
- }
- }
-
private Bitmap getNextBitmap() {
- Bitmap.Config targetConfig = getPreferredConfig();
- Bitmap result = bitmapProvider.obtain(header.width, header.height, targetConfig);
+ Bitmap result = bitmapProvider.obtain(header.width, header.height, BITMAP_CONFIG);
if (result == null) {
- result = Bitmap.createBitmap(header.width, header.height, targetConfig);
+ result = Bitmap.createBitmap(header.width, header.height, BITMAP_CONFIG);
}
setAlpha(result);
return result;
diff --git a/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifHeaderParser.java b/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifHeaderParser.java
index 286a5602..cf61531c 100644
--- a/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifHeaderParser.java
+++ b/third_party/gif_decoder/src/main/java/com/bumptech/glide/gifdecoder/GifHeaderParser.java
@@ -1,5 +1,7 @@
package com.bumptech.glide.gifdecoder;
+import static com.bumptech.glide.gifdecoder.GifDecoder.STATUS_FORMAT_ERROR;
+
import android.util.Log;
import java.nio.BufferUnderflowException;
@@ -7,8 +9,6 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
-import static com.bumptech.glide.gifdecoder.GifDecoder.STATUS_FORMAT_ERROR;
-
/**
* A class responsible for creating {@link com.bumptech.glide.gifdecoder.GifHeader}s from data representing animated
* gifs.
@@ -16,6 +16,11 @@ import static com.bumptech.glide.gifdecoder.GifDecoder.STATUS_FORMAT_ERROR;
public class GifHeaderParser {
public static final String TAG = "GifHeaderParser";
+ // The minimum frame delay in hundredths of a second.
+ static final int MIN_FRAME_DELAY = 3;
+ // The default frame delay in hundredths of a second for GIFs with frame delays less than the minimum.
+ static final int DEFAULT_FRAME_DELAY = 10;
+
private static final int MAX_BLOCK_SIZE = 256;
// Raw data read working array.
private final byte[] block = new byte[MAX_BLOCK_SIZE];
@@ -37,6 +42,11 @@ public class GifHeaderParser {
return this;
}
+ public void clear() {
+ rawData = null;
+ header = null;
+ }
+
private void reset() {
rawData = null;
Arrays.fill(block, (byte) 0);
@@ -147,7 +157,12 @@ public class GifHeaderParser {
}
header.currentFrame.transparency = (packed & 1) != 0;
// Delay in milliseconds.
- header.currentFrame.delay = readShort() * 10;
+ int delayInHundredthsOfASecond = readShort();
+ // TODO: consider allowing -1 to indicate show forever.
+ if (delayInHundredthsOfASecond < MIN_FRAME_DELAY) {
+ delayInHundredthsOfASecond = DEFAULT_FRAME_DELAY;
+ }
+ header.currentFrame.delay = delayInHundredthsOfASecond * 10;
// Transparent color index
header.currentFrame.transIndex = read();
// Block terminator
@@ -275,7 +290,9 @@ public class GifHeaderParser {
tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
}
} catch (BufferUnderflowException e) {
- Log.w(TAG, "Format Error Reading Color Table", e);
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Format Error Reading Color Table", e);
+ }
header.status = STATUS_FORMAT_ERROR;
}
@@ -321,7 +338,9 @@ public class GifHeaderParser {
n += count;
}
} catch (Exception e) {
- Log.w(TAG, "Error Reading Block n: " + n + " count: " + count + " blockSize: " + blockSize, e);
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Error Reading Block n: " + n + " count: " + count + " blockSize: " + blockSize, e);
+ }
header.status = STATUS_FORMAT_ERROR;
}
}
diff --git a/third_party/gif_encoder/build.gradle b/third_party/gif_encoder/build.gradle
deleted file mode 100644
index d13e5e10..00000000
--- a/third_party/gif_encoder/build.gradle
+++ /dev/null
@@ -1,12 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
- compileSdkVersion 19
- buildToolsVersion '19.1.0'
-
- defaultConfig {
- applicationId 'com.bumptech.glide.gifencod:'
- minSdkVersion 10
- targetSdkVersion 19
- }
-}
diff --git a/third_party/gif_encoder/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java b/third_party/gif_encoder/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java
index 2442a0d4..aa1123f6 100644
--- a/third_party/gif_encoder/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java
+++ b/third_party/gif_encoder/src/main/java/com/bumptech/glide/gifencoder/AnimatedGifEncoder.java
@@ -4,6 +4,7 @@ package com.bumptech.glide.gifencoder;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
@@ -35,6 +36,10 @@ import java.io.OutputStream;
*/
public class AnimatedGifEncoder {
+ private static final String TAG = "AnimatedGifEncoder";
+
+ // The minimum % of an images pixels that must be transparent for us to set a transparent index automatically.
+ private static final double MIN_TRANSPARENT_PERCENTAGE = 4d;
private int width; // image size
@@ -384,14 +389,23 @@ public class AnimatedGifEncoder {
int pixelsIndex = 0;
hasTransparentPixels = false;
+ int totalTransparentPixels = 0;
for (final int pixel : pixelsInt) {
if (pixel == Color.TRANSPARENT) {
- hasTransparentPixels = true;
+ totalTransparentPixels++;
}
pixels[pixelsIndex++] = (byte) (pixel & 0xFF);
pixels[pixelsIndex++] = (byte) ((pixel >> 8) & 0xFF);
pixels[pixelsIndex++] = (byte) ((pixel >> 16) & 0xFF);
}
+
+ double transparentPercentage = 100 * totalTransparentPixels / (double) pixelsInt.length;
+ // Assume images with greater where more than n% of the pixels are transparent actually have transparency.
+ // See issue #214.
+ hasTransparentPixels = transparentPercentage > MIN_TRANSPARENT_PERCENTAGE;
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "got pixels for frame with " + transparentPercentage + "% transparent pixels");
+ }
}
/**