All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.stanfy.enroscar.content.loader.LoaderSet Maven / Gradle / Ivy
Go to download
Helper classes and extended abstractions for Android loaders, content resolvers, and DB access.
package com.stanfy.enroscar.content.loader;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.util.SparseIntArray;
/**
* Utility for operating with multiple loaders.
* @author Roman Mazur (Stanfy - http://stanfy.com)
*/
public final class LoaderSet {
/** Index. */
Map, Integer> loaderIndexMapping;
/** Array of core loaders. */
private Description[] descriptions;
/** Results. */
private final Object[] results;
/** Results counter. */
private BitSet resultsSet = new BitSet();
/** Loader manager. */
private final LoaderManager loaderManager;
/** Callbacks. */
private LoaderSetCallback callbacks;
private LoaderSet(final Context context, final Description[] desc, final int totalCount, final LoaderManager loaderManager) {
if (desc == null || desc.length == 0) { throw new IllegalArgumentException("Loaders are not provided"); }
this.descriptions = desc;
for (final Description d : desc) { d.attach(this); }
this.results = new Object[totalCount];
this.loaderManager = loaderManager;
this.loaderIndexMapping = new HashMap, Integer>();
}
/**
* Start loader building.
* @param context context instance
* @return builder for constructing a chain
*/
public static Builder build(final Context context) { return new Builder(context); }
Object[] getResults() { return results; }
public void init(final Bundle arguments, final LoaderSetCallback callbacks) {
touchLoaders(arguments, callbacks, false);
}
public void restart(final Bundle arguments, final LoaderSetCallback callbacks) {
touchLoaders(arguments, callbacks, true);
}
private void touchLoaders(final Bundle arguments, final LoaderSetCallback callbacks, final boolean reload) {
this.callbacks = callbacks;
this.resultsSet.clear();
final LoaderManager loaderManager = LoaderSet.this.loaderManager;
final Description[] descriptions = LoaderSet.this.descriptions;
for (final Description desc : descriptions) {
for (final int id : desc.ids) {
if (!reload) {
loaderManager.initLoader(id, arguments, desc.callbacks);
} else {
loaderManager.restartLoader(id, arguments, desc.callbacks);
}
}
}
}
void onLoadFinished(final Loader loader, final Object data) {
final int index = loaderIndexMapping.get(loader);
results[index] = data;
resultsSet.set(index);
if (resultsSet.cardinality() == results.length) {
callbacks.onLoadFinished(results);
}
}
void onLoaderReset(final Loader loader) {
final Integer index = loaderIndexMapping.get(loader);
if (index != null) {
results[index] = null;
loaderIndexMapping.remove(loader);
}
}
/** Another callbacks wrapper. */
@SuppressWarnings({ "rawtypes", "unchecked" })
private static class CallbacksWrapper implements LoaderCallbacks {
/** Another callbacks. */
private LoaderCallbacks another;
/** IDs mapping. */
private SparseIntArray idsMapping;
/** Chain instance. */
LoaderSet chain;
public CallbacksWrapper(final LoaderCallbacks> another, final SparseIntArray idsMapping) {
this.another = another;
this.idsMapping = idsMapping;
}
@Override
public Loader onCreateLoader(final int id, final Bundle args) {
final Loader result = another.onCreateLoader(id, args);
if (result != null) {
chain.loaderIndexMapping.put(result, idsMapping.get(id));
}
return result;
}
@Override
public void onLoadFinished(final Loader loader, final Object data) {
another.onLoadFinished(loader, data);
chain.onLoadFinished(loader, data);
}
@Override
public void onLoaderReset(final Loader loader) {
another.onLoaderReset(loader);
chain.onLoaderReset(loader);
}
}
/** Another loader description. */
private static class Description {
/** Callbacks. */
final CallbacksWrapper callbacks;
/** Loader identifiers. */
final int[] ids;
Description(final LoaderCallbacks> callbacks, final int[] ids, final int startIndex) {
final SparseIntArray indecies = new SparseIntArray(ids.length);
for (int i = 0; i < ids.length; i++) {
indecies.put(ids[i], startIndex + i);
}
this.callbacks = new CallbacksWrapper(callbacks, indecies);
this.ids = ids;
}
public void attach(final LoaderSet instance) {
callbacks.chain = instance;
}
}
/**
* Adapter to simplify laoder callbacks description.
* @param data type
*/
public abstract static class SetCallbacksAdapter implements LoaderCallbacks {
@Override
public void onLoadFinished(final Loader loader, final D data) {
// nothing
}
@Override
public void onLoaderReset(final Loader loader) {
// nothing
}
}
/**
* Loader set callback.
* @author Roman Mazur (Stanfy - http://stanfy.com)
*/
public interface LoaderSetCallback {
void onLoadFinished(final Object[] data);
}
/** Loader builder. */
public static class Builder {
/** Context. */
private final Context context;
/** Descriptions. */
private final ArrayList descriptions = new ArrayList();
/** Loader manager. */
private LoaderManager loaderManager;
/** Internal counter. */
private int counter = 0;
Builder(final Context context) {
this.context = context;
}
public Builder withManager(final LoaderManager loaderManaer) {
this.loaderManager = loaderManaer;
return this;
}
/**
* @param callbacks loader callbacks instance
* @return identifiers of loaders processed by the defined callbacks
*/
public Builder withCallbacks(final LoaderCallbacks> callbacks, final int... ids) {
descriptions.add(new Description(callbacks, ids, counter));
counter += ids.length;
return this;
}
/** @return loader chain instance */
public LoaderSet create() {
final Description[] desc = new Description[descriptions.size()];
return new LoaderSet(context, descriptions.toArray(desc), counter, loaderManager);
}
}
}