提交 e7e7620f 编写于 作者: S Sam Judd

Avoid concurrent modification in lifecycle impl.

Fixes #375.
上级 c3ee8a28
package com.bumptech.glide.manager;
import com.bumptech.glide.util.Util;
import java.util.Collections;
import java.util.Set;
import java.util.WeakHashMap;
......@@ -44,21 +46,21 @@ class ActivityFragmentLifecycle implements Lifecycle {
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : lifecycleListeners) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : lifecycleListeners) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : lifecycleListeners) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
......
package com.bumptech.glide.manager;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.util.Util;
import java.util.ArrayList;
import java.util.Collections;
......@@ -64,7 +65,7 @@ public class RequestTracker {
*/
public void pauseRequests() {
isPaused = true;
for (Request request : getSnapshot()) {
for (Request request : Util.getSnapshot(requests)) {
if (request.isRunning()) {
request.pause();
pendingRequests.add(request);
......@@ -77,7 +78,7 @@ public class RequestTracker {
*/
public void resumeRequests() {
isPaused = false;
for (Request request : getSnapshot()) {
for (Request request : Util.getSnapshot(requests)) {
if (!request.isComplete() && !request.isCancelled() && !request.isRunning()) {
request.begin();
}
......@@ -89,7 +90,7 @@ public class RequestTracker {
* Cancels all requests and clears their resources.
*/
public void clearRequests() {
for (Request request : getSnapshot()) {
for (Request request : Util.getSnapshot(requests)) {
request.clear();
}
pendingRequests.clear();
......@@ -99,7 +100,7 @@ public class RequestTracker {
* Restarts failed requests and cancels and restarts in progress requests.
*/
public void restartRequests() {
for (Request request : getSnapshot()) {
for (Request request : Util.getSnapshot(requests)) {
if (!request.isComplete() && !request.isCancelled()) {
// Ensure the request will be restarted in onResume.
request.pause();
......@@ -111,17 +112,4 @@ public class RequestTracker {
}
}
}
// Avoids a ConcurrentModificationException when requests are started by another request completing. See #303.
private List<Request> getSnapshot() {
// toArray creates a new ArrayList internally and this way we can guarantee entries will not be
// null. See #322.
List<Request> result = new ArrayList<Request>(requests.size());
// We could also just call new ArrayList<Request>(requests) but that actually creates two new ArrayLists because
// that constructor in ArrayList calls toArray().
for (Request request : requests) {
result.add(request);
}
return result;
}
}
......@@ -8,6 +8,9 @@ import android.os.Looper;
import com.bumptech.glide.request.target.Target;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
/**
......@@ -157,9 +160,25 @@ public final class Util {
}
/**
* Creates a {@link java.util.Queue} of the given size using Glide's preferred implementation.
* Returns a {@link java.util.Queue} of the given size using Glide's preferred implementation.
*/
public static <T> Queue<T> createQueue(int size) {
return new ArrayDeque<T>(size);
}
/**
* Returns a copy of the given list that is safe to iterate over and perform actions that may
* modify the original list.
*
* <p> See #303 and #375. </p>
*/
public static <T> List<T> getSnapshot(Collection<T> other) {
// toArray creates a new ArrayList internally and this way we can guarantee entries will not
// be null. See #322.
List<T> result = new ArrayList<T>(other.size());
for (T item : other) {
result.add(item);
}
return result;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册