diff --git a/.gitignore b/.gitignore
index 37ac0c17dd..e90dca6f0d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,5 +23,7 @@ docs/**/*
# Intellij
*.iml
+*.ipr
+*.iws
.idea/**
!.idea/codeStyleSettings.xml
diff --git a/build.gradle b/build.gradle
index d08837520a..ac4c7b5605 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,7 +15,7 @@ buildscript {
dependencies {
classpath "com.android.tools.build:gradle:${ANDROID_GRADLE_VERSION}"
if (!hasProperty('DISABLE_ERROR_PRONE')) {
- classpath "net.ltgt.gradle:gradle-errorprone-plugin:${ERROR_PRONE_VERSION}"
+ classpath "net.ltgt.gradle:gradle-errorprone-plugin:${ERROR_PRONE_PLUGIN_VERSION}"
}
classpath "se.bjurr.violations:violations-gradle-plugin:${VIOLATIONS_PLUGIN_VERSION}"
}
diff --git a/checkstyle.xml b/checkstyle.xml
index 42a2c8a502..c2a00167d8 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -73,7 +73,7 @@
-
+
diff --git a/gradle.properties b/gradle.properties
index ff78f7121c..dd0b3a3ae8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -32,9 +32,10 @@ JSR_305_VERSION=3.0.2
AUTO_SERVICE_VERSION=1.0-rc3
JAVAPOET_VERSION=1.9.0
-PMD_VERSION=5.4.0
+PMD_VERSION=5.8.1
FINDBUGS_VERSION=3.0.0
-ERROR_PRONE_VERSION=0.0.13
+ERROR_PRONE_VERSION=2.1.4-SNAPSHOT
+ERROR_PRONE_PLUGIN_VERSION=0.0.13
VIOLATIONS_PLUGIN_VERSION=1.3
COMPILE_SDK_VERSION=27
diff --git a/integration/gifencoder/src/test/java/com/bumptech/glide/integration/gifencoder/ReEncodingGifResourceEncoderTest.java b/integration/gifencoder/src/test/java/com/bumptech/glide/integration/gifencoder/ReEncodingGifResourceEncoderTest.java
index f4a971d977..641dc7357f 100644
--- a/integration/gifencoder/src/test/java/com/bumptech/glide/integration/gifencoder/ReEncodingGifResourceEncoderTest.java
+++ b/integration/gifencoder/src/test/java/com/bumptech/glide/integration/gifencoder/ReEncodingGifResourceEncoderTest.java
@@ -3,7 +3,6 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
@@ -95,6 +94,8 @@ public void setUp() {
@After
public void tearDown() {
+ // GC before delete() to release files on Windows (https://stackoverflow.com/a/4213208/253468)
+ System.gc();
if (file.exists() && !file.delete()) {
throw new RuntimeException("Failed to delete file");
}
@@ -120,8 +121,6 @@ public void testEncodeStrategy_withEncodeTransformationFalse_returnsSource() {
@Test
public void testEncode_withEncodeTransformationFalse_writesSourceDataToStream()
throws IOException {
- // Most likely an instance of http://stackoverflow.com/q/991489/253468
- assumeTrue(!System.getProperty("os.name").startsWith("Windows"));
options.set(ReEncodingGifResourceEncoder.ENCODE_TRANSFORMATION, false);
String expected = "testString";
byte[] data = expected.getBytes("UTF-8");
@@ -134,7 +133,6 @@ public void testEncode_withEncodeTransformationFalse_writesSourceDataToStream()
@Test
public void testEncode_WithEncodeTransformationFalse_whenOsThrows_returnsFalse()
throws IOException {
-
options.set(ReEncodingGifResourceEncoder.ENCODE_TRANSFORMATION, false);
byte[] data = "testString".getBytes("UTF-8");
when(gifDrawable.getBuffer()).thenReturn(ByteBuffer.wrap(data));
@@ -312,10 +310,7 @@ public void testRecyclesFrameResourceAfterWritingIfFrameResourceIsNotTransformed
}
@Test
- public void testWritesBytesDirectlyToDiskIfTransformationIsUnitTransformation()
- throws IOException {
- // Most likely an instance of http://stackoverflow.com/q/991489/253468
- assumeTrue(!System.getProperty("os.name").startsWith("Windows"));
+ public void testWritesBytesDirectlyToDiskIfTransformationIsUnitTransformation() {
when(gifDrawable.getFrameTransformation()).thenReturn(UnitTransformation.get());
String expected = "expected";
when(gifDrawable.getBuffer()).thenReturn(ByteBuffer.wrap(expected.getBytes()));
diff --git a/library/build.gradle b/library/build.gradle
index 22d3219330..8672d9ddb7 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -20,6 +20,10 @@ dependencies {
testImplementation "org.robolectric:robolectric:${ROBOLECTRIC_VERSION}"
testImplementation "com.squareup.okhttp3:mockwebserver:${MOCKWEBSERVER_VERSION}"
testImplementation "com.android.support:support-v4:${ANDROID_SUPPORT_VERSION}"
+
+ if (project.plugins.hasPlugin('net.ltgt.errorprone')) {
+ errorprone "com.google.errorprone:error_prone_core:${ERROR_PRONE_VERSION}"
+ }
}
android.testOptions.unitTests.all { Test testTask ->
diff --git a/library/pmd-ruleset.xml b/library/pmd-ruleset.xml
index 76249e191d..da8c961e38 100644
--- a/library/pmd-ruleset.xml
+++ b/library/pmd-ruleset.xml
@@ -3,15 +3,17 @@
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">
- This ruleset was created from PMD.rul
+ Check for flaws in Glide's codebase.
-
-
-
+
+
+
+
+
@@ -28,31 +30,39 @@
+
+
+
+
+
+
+
-
-
-
-
+
+
-
-
-
-
-
-
+
-
-
diff --git a/library/src/main/java/com/bumptech/glide/RequestBuilder.java b/library/src/main/java/com/bumptech/glide/RequestBuilder.java
index 18dcbbce9f..ec4d145cd5 100644
--- a/library/src/main/java/com/bumptech/glide/RequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/RequestBuilder.java
@@ -30,6 +30,7 @@
import com.bumptech.glide.request.target.ViewTarget;
import com.bumptech.glide.signature.ApplicationVersionSignature;
import com.bumptech.glide.util.Preconditions;
+import com.bumptech.glide.util.Synthetic;
import com.bumptech.glide.util.Util;
import java.io.File;
import java.net.URL;
@@ -572,7 +573,7 @@ public > Y into(@NonNull Y target) {
}
@NonNull
- private > Y into(
+ @Synthetic > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener) {
return into(target, targetListener, getMutableOptions());
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/ActiveResources.java b/library/src/main/java/com/bumptech/glide/load/engine/ActiveResources.java
index 79f0573258..19671164c0 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/ActiveResources.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/ActiveResources.java
@@ -91,7 +91,8 @@ EngineResource> get(Key key) {
return active;
}
- private void cleanupActiveReference(@NonNull ResourceWeakReference ref) {
+ @SuppressWarnings("WeakerAccess")
+ @Synthetic void cleanupActiveReference(@NonNull ResourceWeakReference ref) {
Util.assertMainThread();
activeEngineResources.remove(ref.key);
@@ -112,22 +113,7 @@ private ReferenceQueue> getReferenceQueue() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- ResourceWeakReference ref;
- while (!isShutdown) {
- try {
- ref = (ResourceWeakReference) resourceReferenceQueue.remove();
- mainHandler.obtainMessage(MSG_CLEAN_REF, ref).sendToTarget();
-
- // This section for testing only.
- DequeuedResourceCallback current = cb;
- if (current != null) {
- current.onResourceDequeued();
- }
- // End for testing only.
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
+ cleanReferenceQueue();
}
}, "glide-active-resources");
cleanReferenceQueueThread.start();
@@ -135,6 +121,25 @@ public void run() {
return resourceReferenceQueue;
}
+ @SuppressWarnings("WeakerAccess")
+ @Synthetic void cleanReferenceQueue() {
+ while (!isShutdown) {
+ try {
+ ResourceWeakReference ref = (ResourceWeakReference) resourceReferenceQueue.remove();
+ mainHandler.obtainMessage(MSG_CLEAN_REF, ref).sendToTarget();
+
+ // This section for testing only.
+ DequeuedResourceCallback current = cb;
+ if (current != null) {
+ current.onResourceDequeued();
+ }
+ // End for testing only.
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
@VisibleForTesting
void setDequeuedResourceCallback(DequeuedResourceCallback cb) {
this.cb = cb;
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 888bf71d3b..35a35ce80f 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
@@ -41,26 +41,22 @@ class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
Poolable {
private static final String TAG = "DecodeJob";
- @SuppressWarnings("WeakerAccess")
- @Synthetic
- final DecodeHelper decodeHelper = new DecodeHelper<>();
+ private final DecodeHelper decodeHelper = new DecodeHelper<>();
private final List throwables = new ArrayList<>();
private final StateVerifier stateVerifier = StateVerifier.newInstance();
private final DiskCacheProvider diskCacheProvider;
private final Pools.Pool> pool;
- @SuppressWarnings("WeakerAccess")
- @Synthetic
- final DeferredEncodeManager> deferredEncodeManager = new DeferredEncodeManager<>();
+ private final DeferredEncodeManager> deferredEncodeManager = new DeferredEncodeManager<>();
private final ReleaseManager releaseManager = new ReleaseManager();
private GlideContext glideContext;
- @SuppressWarnings("WeakerAccess") @Synthetic Key signature;
+ private Key signature;
private Priority priority;
private EngineKey loadKey;
- @SuppressWarnings("WeakerAccess") @Synthetic int width;
- @SuppressWarnings("WeakerAccess") @Synthetic int height;
- @SuppressWarnings("WeakerAccess") @Synthetic DiskCacheStrategy diskCacheStrategy;
- @SuppressWarnings("WeakerAccess") @Synthetic Options options;
+ private int width;
+ private int height;
+ private DiskCacheStrategy diskCacheStrategy;
+ private Options options;
private Callback callback;
private int order;
private Stage stage;
@@ -69,7 +65,7 @@ class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
private boolean onlyRetrieveFromCache;
private Thread currentThread;
- @SuppressWarnings("WeakerAccess") @Synthetic Key currentSourceKey;
+ private Key currentSourceKey;
private Key currentAttemptingKey;
private Object currentData;
private DataSource currentDataSource;
@@ -521,6 +517,65 @@ public StateVerifier getVerifier() {
return stateVerifier;
}
+ @Synthetic Resource onResourceDecoded(DataSource dataSource, Resource decoded) {
+ @SuppressWarnings("unchecked")
+ Class resourceSubClass = (Class) decoded.get().getClass();
+ Transformation appliedTransformation = null;
+ Resource transformed = decoded;
+ if (dataSource != DataSource.RESOURCE_DISK_CACHE) {
+ appliedTransformation = decodeHelper.getTransformation(resourceSubClass);
+ transformed = appliedTransformation.transform(glideContext, decoded, width, height);
+ }
+ // TODO: Make this the responsibility of the Transformation.
+ if (!decoded.equals(transformed)) {
+ decoded.recycle();
+ }
+
+ final EncodeStrategy encodeStrategy;
+ final ResourceEncoder encoder;
+ if (decodeHelper.isResourceEncoderAvailable(transformed)) {
+ encoder = decodeHelper.getResultEncoder(transformed);
+ encodeStrategy = encoder.getEncodeStrategy(options);
+ } else {
+ encoder = null;
+ encodeStrategy = EncodeStrategy.NONE;
+ }
+
+ Resource result = transformed;
+ boolean isFromAlternateCacheKey = !decodeHelper.isSourceKey(currentSourceKey);
+ if (diskCacheStrategy.isResourceCacheable(isFromAlternateCacheKey, dataSource,
+ encodeStrategy)) {
+ if (encoder == null) {
+ throw new Registry.NoResultEncoderAvailableException(transformed.get().getClass());
+ }
+ final Key key;
+ switch (encodeStrategy) {
+ case SOURCE:
+ key = new DataCacheKey(currentSourceKey, signature);
+ break;
+ case TRANSFORMED:
+ key =
+ new ResourceCacheKey(
+ decodeHelper.getArrayPool(),
+ currentSourceKey,
+ signature,
+ width,
+ height,
+ appliedTransformation,
+ resourceSubClass,
+ options);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown strategy: " + encodeStrategy);
+ }
+
+ LockedResource lockedResult = LockedResource.obtain(transformed);
+ deferredEncodeManager.init(key, encoder, lockedResult);
+ result = lockedResult;
+ }
+ return result;
+ }
+
private final class DecodeCallback implements DecodePath.DecodeCallback {
private final DataSource dataSource;
@@ -532,66 +587,7 @@ private final class DecodeCallback implements DecodePath.DecodeCallback {
@Override
public Resource onResourceDecoded(Resource decoded) {
- Class resourceSubClass = getResourceClass(decoded);
- Transformation appliedTransformation = null;
- Resource transformed = decoded;
- if (dataSource != DataSource.RESOURCE_DISK_CACHE) {
- appliedTransformation = decodeHelper.getTransformation(resourceSubClass);
- transformed = appliedTransformation.transform(glideContext, decoded, width, height);
- }
- // TODO: Make this the responsibility of the Transformation.
- if (!decoded.equals(transformed)) {
- decoded.recycle();
- }
-
- final EncodeStrategy encodeStrategy;
- final ResourceEncoder encoder;
- if (decodeHelper.isResourceEncoderAvailable(transformed)) {
- encoder = decodeHelper.getResultEncoder(transformed);
- encodeStrategy = encoder.getEncodeStrategy(options);
- } else {
- encoder = null;
- encodeStrategy = EncodeStrategy.NONE;
- }
-
- Resource result = transformed;
- boolean isFromAlternateCacheKey = !decodeHelper.isSourceKey(currentSourceKey);
- if (diskCacheStrategy.isResourceCacheable(isFromAlternateCacheKey, dataSource,
- encodeStrategy)) {
- if (encoder == null) {
- throw new Registry.NoResultEncoderAvailableException(transformed.get().getClass());
- }
- final Key key;
- switch (encodeStrategy) {
- case SOURCE:
- key = new DataCacheKey(currentSourceKey, signature);
- break;
- case TRANSFORMED:
- key =
- new ResourceCacheKey(
- decodeHelper.getArrayPool(),
- currentSourceKey,
- signature,
- width,
- height,
- appliedTransformation,
- resourceSubClass,
- options);
- break;
- default:
- throw new IllegalArgumentException("Unknown strategy: " + encodeStrategy);
- }
-
- LockedResource lockedResult = LockedResource.obtain(transformed);
- deferredEncodeManager.init(key, encoder, lockedResult);
- result = lockedResult;
- }
- return result;
- }
-
- @SuppressWarnings("unchecked")
- private Class getResourceClass(Resource resource) {
- return (Class) resource.get().getClass();
+ return DecodeJob.this.onResourceDecoded(dataSource, decoded);
}
}
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 4431689fde..a5b89f53dd 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
@@ -111,7 +111,7 @@ static String getBitmapString(int size) {
static class KeyPool extends BaseKeyPool {
public Key get(int size) {
- Key result = get();
+ Key result = super.get();
result.init(size);
return result;
}
@@ -149,6 +149,8 @@ public int hashCode() {
return size;
}
+ // PMD.AccessorMethodGeneration: https://github.com/pmd/pmd/issues/807
+ @SuppressWarnings("PMD.AccessorMethodGeneration")
@Override
public String toString() {
return getBitmapString(size);
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/cache/MemorySizeCalculator.java b/library/src/main/java/com/bumptech/glide/load/engine/cache/MemorySizeCalculator.java
index b697ca5568..b9b7211a18 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/cache/MemorySizeCalculator.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/cache/MemorySizeCalculator.java
@@ -9,6 +9,7 @@
import android.util.DisplayMetrics;
import android.util.Log;
import com.bumptech.glide.util.Preconditions;
+import com.bumptech.glide.util.Synthetic;
/**
* A calculator that tries to intelligently determine cache sizes for a given device based on some
@@ -115,7 +116,7 @@ private String toMb(int bytes) {
}
@TargetApi(Build.VERSION_CODES.KITKAT)
- private static boolean isLowMemoryDevice(ActivityManager activityManager) {
+ @Synthetic static boolean isLowMemoryDevice(ActivityManager activityManager) {
// Explicitly check with an if statement, on some devices both parts of boolean expressions
// can be evaluated even if we'd normally expect a short circuit.
//noinspection SimplifiableIfStatement
@@ -149,17 +150,17 @@ public static final class Builder {
// 4MB.
static final int ARRAY_POOL_SIZE_BYTES = 4 * 1024 * 1024;
- private final Context context;
+ @Synthetic final Context context;
- // Modifiable for testing.
- private ActivityManager activityManager;
- private ScreenDimensions screenDimensions;
+ // Modifiable (non-final) for testing.
+ @Synthetic ActivityManager activityManager;
+ @Synthetic ScreenDimensions screenDimensions;
- private float memoryCacheScreens = MEMORY_CACHE_TARGET_SCREENS;
- private float bitmapPoolScreens = BITMAP_POOL_TARGET_SCREENS;
- private float maxSizeMultiplier = MAX_SIZE_MULTIPLIER;
- private float lowMemoryMaxSizeMultiplier = LOW_MEMORY_MAX_SIZE_MULTIPLIER;
- private int arrayPoolSizeBytes = ARRAY_POOL_SIZE_BYTES;
+ @Synthetic float memoryCacheScreens = MEMORY_CACHE_TARGET_SCREENS;
+ @Synthetic float bitmapPoolScreens = BITMAP_POOL_TARGET_SCREENS;
+ @Synthetic float maxSizeMultiplier = MAX_SIZE_MULTIPLIER;
+ @Synthetic float lowMemoryMaxSizeMultiplier = LOW_MEMORY_MAX_SIZE_MULTIPLIER;
+ @Synthetic int arrayPoolSizeBytes = ARRAY_POOL_SIZE_BYTES;
public Builder(Context context) {
this.context = context;
diff --git a/library/src/main/java/com/bumptech/glide/load/engine/executor/GlideExecutor.java b/library/src/main/java/com/bumptech/glide/load/engine/executor/GlideExecutor.java
index 57fecd8939..7f8845534d 100644
--- a/library/src/main/java/com/bumptech/glide/load/engine/executor/GlideExecutor.java
+++ b/library/src/main/java/com/bumptech/glide/load/engine/executor/GlideExecutor.java
@@ -433,7 +433,8 @@ public synchronized Thread newThread(@NonNull Runnable runnable) {
final Thread result = new Thread(runnable, "glide-" + name + "-thread-" + threadNum) {
@Override
public void run() {
- android.os.Process.setThreadPriority(DEFAULT_PRIORITY);
+ // why PMD suppression is needed: https://github.com/pmd/pmd/issues/808
+ android.os.Process.setThreadPriority(DEFAULT_PRIORITY); //NOPMD AccessorMethodGeneration
if (preventNetworkOperations) {
StrictMode.setThreadPolicy(
new ThreadPolicy.Builder()
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java
index bcd23762d3..9275e34297 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java
@@ -69,7 +69,7 @@ public Resource transform(@NonNull Context context,
}
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "PMD.UnnecessaryLocalBeforeReturn"})
private Resource newDrawableResource(
Context context, Resource transformed) {
Resource extends Drawable> result =
diff --git a/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java b/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java
index b137956580..23fc35355e 100644
--- a/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java
+++ b/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java
@@ -28,8 +28,7 @@ public class RequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
private final RequestManagerTreeNode requestManagerTreeNode =
new FragmentRequestManagerTreeNode();
- private final HashSet childRequestManagerFragments =
- new HashSet<>();
+ private final Set childRequestManagerFragments = new HashSet<>();
@Nullable private RequestManager requestManager;
@Nullable private RequestManagerFragment rootRequestManagerFragment;
@@ -86,7 +85,7 @@ private void removeChildRequestManagerFragment(RequestManagerFragment child) {
* our parent is the fragment that we are annotating).
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
- private Set getDescendantRequestManagerFragments() {
+ @Synthetic Set getDescendantRequestManagerFragments() {
if (this.equals(rootRequestManagerFragment)) {
return Collections.unmodifiableSet(childRequestManagerFragments);
} else if (rootRequestManagerFragment == null
@@ -95,7 +94,7 @@ private Set getDescendantRequestManagerFragments() {
// so just return an empty set.
return Collections.emptySet();
} else {
- HashSet descendants = new HashSet<>();
+ Set descendants = new HashSet<>();
for (RequestManagerFragment fragment : rootRequestManagerFragment
.getDescendantRequestManagerFragments()) {
if (isDescendant(fragment.getParentFragment())) {
@@ -212,7 +211,7 @@ private class FragmentRequestManagerTreeNode implements RequestManagerTreeNode {
@Override
public Set getDescendants() {
Set descendantFragments = getDescendantRequestManagerFragments();
- HashSet descendants = new HashSet<>(descendantFragments.size());
+ Set descendants = new HashSet<>(descendantFragments.size());
for (RequestManagerFragment fragment : descendantFragments) {
if (fragment.getRequestManager() != null) {
descendants.add(fragment.getRequestManager());
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 1307a34c15..a44bb02e22 100644
--- a/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java
+++ b/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java
@@ -27,8 +27,7 @@ public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
private final RequestManagerTreeNode requestManagerTreeNode =
new SupportFragmentRequestManagerTreeNode();
- private final HashSet childRequestManagerFragments =
- new HashSet<>();
+ private final Set childRequestManagerFragments = new HashSet<>();
@Nullable private SupportRequestManagerFragment rootRequestManagerFragment;
@Nullable private RequestManager requestManager;
@@ -86,13 +85,13 @@ private void removeChildRequestManagerFragment(SupportRequestManagerFragment chi
* Returns the set of fragments that this RequestManagerFragment's parent is a parent to. (i.e.
* our parent is the fragment that we are annotating).
*/
- private Set getDescendantRequestManagerFragments() {
+ @Synthetic Set getDescendantRequestManagerFragments() {
if (rootRequestManagerFragment == null) {
return Collections.emptySet();
} else if (this.equals(rootRequestManagerFragment)) {
return Collections.unmodifiableSet(childRequestManagerFragments);
} else {
- HashSet descendants = new HashSet<>();
+ Set descendants = new HashSet<>();
for (SupportRequestManagerFragment fragment : rootRequestManagerFragment
.getDescendantRequestManagerFragments()) {
if (isDescendant(fragment.getParentFragmentUsingHint())) {
@@ -203,7 +202,7 @@ private class SupportFragmentRequestManagerTreeNode implements RequestManagerTre
public Set getDescendants() {
Set descendantFragments =
getDescendantRequestManagerFragments();
- HashSet descendants = new HashSet<>(descendantFragments.size());
+ Set descendants = new HashSet<>(descendantFragments.size());
for (SupportRequestManagerFragment fragment : descendantFragments) {
if (fragment.getRequestManager() != null) {
descendants.add(fragment.getRequestManager());
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 90284f80c4..903522fc07 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
@@ -8,6 +8,7 @@
import android.support.annotation.Nullable;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.request.transition.Transition;
+import com.bumptech.glide.util.Synthetic;
/**
* A one time use {@link com.bumptech.glide.request.target.Target} class that loads a resource into
@@ -51,7 +52,8 @@ public void onResourceReady(@NonNull Z resource, @Nullable Transition super Z>
HANDLER.obtainMessage(MESSAGE_CLEAR, this).sendToTarget();
}
- private void clear() {
+ @SuppressWarnings("WeakerAccess")
+ @Synthetic void clear() {
requestManager.clear(this);
}
}
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 e017e209b3..be500d87ca 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
@@ -112,26 +112,36 @@ public final ViewTarget clearOnDetach() {
attachStateListener = new OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
- Request request = getRequest();
- if (request != null && request.isPaused()) {
- request.begin();
- }
+ resumeMyRequest();
}
@Override
public void onViewDetachedFromWindow(View v) {
- Request request = getRequest();
- if (request != null && !request.isCancelled() && !request.isPaused()) {
- isClearedByUs = true;
- request.pause();
- isClearedByUs = false;
- }
+ pauseMyRequest();
}
};
maybeAddAttachStateListener();
return this;
}
+ @SuppressWarnings("WeakerAccess")
+ @Synthetic void resumeMyRequest() {
+ Request request = getRequest();
+ if (request != null && request.isPaused()) {
+ request.begin();
+ }
+ }
+
+ @SuppressWarnings("WeakerAccess")
+ @Synthetic void pauseMyRequest() {
+ Request request = getRequest();
+ if (request != null && !request.isCancelled() && !request.isPaused()) {
+ isClearedByUs = true;
+ request.pause();
+ isClearedByUs = false;
+ }
+ }
+
/**
* Indicates that Glide should always wait for any pending layout pass before checking
* for the size an {@link View}.
@@ -151,6 +161,7 @@ public void onViewDetachedFromWindow(View v) {
* still be used instead of the {@link View}'s dimensions even if this method is called. This
* parameter is a fallback only.
*/
+ @SuppressWarnings("WeakerAccess")
@NonNull
public final ViewTarget waitForLayout() {
sizeDeterminer.waitForLayout = true;
@@ -319,7 +330,7 @@ static final class SizeDeterminer {
static Integer maxDisplayLength;
private final View view;
private final List cbs = new ArrayList<>();
- private boolean waitForLayout;
+ @Synthetic boolean waitForLayout;
@Nullable private SizeDeterminerLayoutListener layoutListener;
diff --git a/library/src/test/java/com/bumptech/glide/load/engine/cache/DiskLruCacheWrapperTest.java b/library/src/test/java/com/bumptech/glide/load/engine/cache/DiskLruCacheWrapperTest.java
index 06e2b7c126..24a1098e77 100644
--- a/library/src/test/java/com/bumptech/glide/load/engine/cache/DiskLruCacheWrapperTest.java
+++ b/library/src/test/java/com/bumptech/glide/load/engine/cache/DiskLruCacheWrapperTest.java
@@ -3,6 +3,7 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.mock;
import android.support.annotation.NonNull;
@@ -53,6 +54,8 @@ private static void deleteRecursive(File file) {
}
}
}
+ // GC before delete() to release files on Windows (https://stackoverflow.com/a/4213208/253468)
+ System.gc();
if (!file.delete() && file.exists()) {
throw new RuntimeException("Failed to delete: " + file);
}
@@ -139,6 +142,7 @@ public boolean write(@NonNull File file) {
// Tests #2465.
@Test
public void clearDiskCache_afterOpeningDiskCache_andDeleteDirectoryOutsideGlide_doesNotThrow() {
+ assumeTrue("A file handle is likely open, so cannot delete dir", !Util.isWindows());
DiskCache cache = DiskLruCacheWrapper.create(dir, 1024 * 1024);
cache.get(mock(Key.class));
deleteRecursive(dir);
@@ -148,6 +152,7 @@ public void clearDiskCache_afterOpeningDiskCache_andDeleteDirectoryOutsideGlide_
// Tests #2465.
@Test
public void get_afterDeleteDirectoryOutsideGlideAndClose_doesNotThrow() {
+ assumeTrue("A file handle is likely open, so cannot delete dir", !Util.isWindows());
DiskCache cache = DiskLruCacheWrapper.create(dir, 1024 * 1024);
cache.get(mock(Key.class));
deleteRecursive(dir);
diff --git a/library/src/test/java/com/bumptech/glide/load/model/StreamEncoderTest.java b/library/src/test/java/com/bumptech/glide/load/model/StreamEncoderTest.java
index f266fb214e..07dd655dc2 100644
--- a/library/src/test/java/com/bumptech/glide/load/model/StreamEncoderTest.java
+++ b/library/src/test/java/com/bumptech/glide/load/model/StreamEncoderTest.java
@@ -30,6 +30,8 @@ public void setUp() {
@After
public void tearDown() {
+ // GC before delete() to release files on Windows (https://stackoverflow.com/a/4213208/253468)
+ System.gc();
if (!file.delete()) {
throw new IllegalStateException("Failed to delete: " + file);
}
diff --git a/library/src/test/java/com/bumptech/glide/load/model/StringLoaderTest.java b/library/src/test/java/com/bumptech/glide/load/model/StringLoaderTest.java
index f772ad3ea5..b6554eabff 100644
--- a/library/src/test/java/com/bumptech/glide/load/model/StringLoaderTest.java
+++ b/library/src/test/java/com/bumptech/glide/load/model/StringLoaderTest.java
@@ -15,7 +15,6 @@
import com.bumptech.glide.tests.Util;
import com.bumptech.glide.util.Preconditions;
import java.io.File;
-import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,7 +41,7 @@ public class StringLoaderTest {
private Options options;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
MockitoAnnotations.initMocks(this);
options = new Options();
@@ -51,9 +50,9 @@ public void setUp() throws Exception {
}
@Test
- public void testHandlesPaths() throws IOException {
- // TODO on windows it will fail with schema being the drive letter (C:\... -> C)
- assumeTrue(!Util.isWindows());
+ public void testHandlesPaths() {
+ // TODO fix drive letter parsing somehow
+ assumeTrue("it will fail with schema being the drive letter (C:\\... -> C)", !Util.isWindows());
File f = RuntimeEnvironment.application.getCacheDir();
Uri expected = Uri.fromFile(f);
@@ -69,8 +68,6 @@ public void testHandlesPaths() throws IOException {
@Test
public void testCanHandleComplexFilePaths() {
- assumeTrue(!Util.isWindows());
-
String testPath =
"/storage/emulated/0/DCIM/Camera/IMG_20140520_100001:nopm:.jpg,mimeType=image/jpeg,"
+ "2448x3264,orientation=0,date=Tue";
@@ -86,7 +83,7 @@ public void testCanHandleComplexFilePaths() {
}
@Test
- public void testHandlesFileUris() throws IOException {
+ public void testHandlesFileUris() {
File f = RuntimeEnvironment.application.getCacheDir();
Uri expected = Uri.fromFile(f);
@@ -101,7 +98,7 @@ public void testHandlesFileUris() throws IOException {
}
@Test
- public void testHandlesResourceUris() throws IOException {
+ public void testHandlesResourceUris() {
Uri resourceUri = Uri.parse("android.resource://com.bumptech.glide.tests/raw/ic_launcher");
when(uriLoader.buildLoadData(eq(resourceUri), eq(IMAGE_SIDE), eq(IMAGE_SIDE), eq(options)))
diff --git a/library/src/test/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoderTest.java b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoderTest.java
index 06f071de71..9db7c49946 100644
--- a/library/src/test/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoderTest.java
+++ b/library/src/test/java/com/bumptech/glide/load/resource/bitmap/BitmapEncoderTest.java
@@ -126,6 +126,8 @@ String encode() throws IOException {
}
void tearDown() {
+ // GC before delete() to release files on Windows (https://stackoverflow.com/a/4213208/253468)
+ System.gc();
if (file.exists() && !file.delete()) {
throw new IllegalStateException("Failed to delete: " + file);
}