
com.azcltd.fluffyimageloader.loader.ResourcesLoadingManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fluffy-image-loader Show documentation
Show all versions of fluffy-image-loader Show documentation
Library that helps loading and caching images in Android applications
The newest version!
package com.azcltd.fluffyimageloader.loader;
import java.util.*;
/**
* This class helps synchronize and manage resources' Uris queue.
*
* It also provide functionality to maintain set of "specs objects" (see {@code ResourceSpecs} class) for one Uri (i.e. if resource from
* given Uri was already scheduled for loading we can avoid scheduling another loading process for same Uri).
*
* Also each Uri can be in several loading states (see {@code LoadingState} enum).
*/
class ResourcesLoadingManager {
private Map>> mMap = new LinkedHashMap>>();
private Map mStateMap = new LinkedHashMap();
private Map mStartTimeMap = new HashMap();
private Map mResultsMap = new HashMap();
/**
* Adding given specs object to loading queue. If corresponding resource Uri was already scheduled for loading but was not yet loaded,
* then this specs object will be appended to the list of pending specs for given Uri. When resource for given Uri will be loaded all
* corresponding "waiting" specs objects will be notified.
*
* After specs were added {@code this.notify()} method will be called to wake up first waiting thread.
*/
public synchronized void addSpecs(ResourceSpecs specs) {
String uri = specs.getUri();
Set> list = mMap.get(uri);
if (list == null) {
list = new HashSet>();
mMap.put(uri, list);
mStartTimeMap.put(uri, System.currentTimeMillis() + specs.getDelay());
}
list.add(specs);
LoadingState state = mStateMap.get(uri);
if (state == null) {
mStateMap.put(uri, LoadingState.WAIT_MANAGING);
} else if (state == LoadingState.DOWNLOADING) {
specs.onStart();
}
notify();
}
/**
* @return Snapshot (copy) set of specs objects currently waiting for given Uri to be loaded.
* May return {@code null} if given Uri is no more in the loading queue. I.e. given Uri was already loaded and all waiting specs
* are already notified. Or if there are no more valid (not outdated) specs objects for given Uri.
* @see {@link #isOutdated(String)} method
*/
public synchronized Set> getSpecsList(String uri) {
return mMap.containsKey(uri) ? new HashSet>(mMap.get(uri)) : null;
}
/**
* Specs object may be reused several times and new resource Uri can be set for loading. If another Uris was set for some of waiting
* specs objects we should remove them from set of waiting objects for given Uri.
*
* This approach is designed for loading images into ListView or similar views where if items were scrolled very fast we should avoid
* loading "outdated" and show them in wrong positions in list.
*
* @param uri
* @return True if all corresponding specs objects for given {@code uri} were outdated. False otherwise.
*/
public synchronized boolean isOutdated(String uri) {
Set> set = mMap.get(uri);
if (set == null) return true;
Iterator> iter = set.iterator();
while (iter.hasNext()) {
String actualUri = iter.next().getUri();
if (actualUri == null || !actualUri.equals(uri)) iter.remove();
}
if (set.isEmpty()) {
remove(uri);
return true;
} else {
return false;
}
}
/**
* Method to retrieve stored loaded object for given Uri.
*/
public synchronized T getResult(String uri) {
return mResultsMap.get(uri);
}
/**
* Method for storing loaded object for given Uri.
* Do nothing if given Uri is not in queue.
*/
public synchronized void setResult(String uri, T res) {
if (mMap.containsKey(uri)) mResultsMap.put(uri, res);
}
/**
* Removes given Uri from queue and returns all corresponding sepcs objects.
*
* @return May return {@code null} if specified {@code uri} was already deleted from queue (i.e. all specs were outdated)
*/
public synchronized Set> remove(String uri) {
mResultsMap.remove(uri);
mStateMap.remove(uri);
mStartTimeMap.remove(uri);
return mMap.remove(uri);
}
/**
* Setting current loading state for Uri.
* Do nothing if given Uri is not in queue.
*
* @see LoadingState
*/
public synchronized void setState(String uri, LoadingState state) {
if (mMap.containsKey(uri)) mStateMap.put(uri, state);
}
/**
* Getting current loading state for Uri.
*
* @return Loading state. May return {@code null} if given Uri was already removed from loading queue.
* @see LoadingState
*/
public synchronized LoadingState getState(String uri) {
return mStateMap.get(uri);
}
/**
* Finds and returns first Uri waiting to be managed.
*
* @return First Uri to process. May return {@code null} if no Uris are waiting to be managed.
* @see {@literal LoadingState.WAIT_MANAGING}
*/
public synchronized String getNextUriToManage(boolean skipDelayCheck) {
for (String uri : mStateMap.keySet()) {
if (mStateMap.get(uri) == LoadingState.WAIT_MANAGING
&& (skipDelayCheck || System.currentTimeMillis() - mStartTimeMap.get(uri) > 0)) {
return uri;
}
}
return null;
}
public static enum LoadingState {
WAIT_MANAGING, MANAGING, WAIT_DOWNLOADING, DOWNLOADING, WAIT_LOADING, LOADING, WAIT_DISPLAYING;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy