com.octo.android.robospice
Class SpiceManager

java.lang.Object
  extended by com.octo.android.robospice.SpiceManager
All Implemented Interfaces:
Runnable
Direct Known Subclasses:
BitmapSpiceManager, OkHttpBitmapSpiceManager

public class SpiceManager
extends Object
implements Runnable

The instances of this class allow to acces the SpiceService.
They are tied to activities and obtain a local binding to the SpiceService. When binding occurs, the SpiceManager will send commadnds to the SpiceService, to execute requests, clear cache, prevent listeners from being called and so on. Basically, all features of the SpiceService are accessible from the SpiceManager. It acts as an asynchronous proxy : every call to a SpiceService method is asynchronous and will occur as soon as possible when the SpiceManager successfully binds to the service.

Author:
jva, sni, mwa

Nested Class Summary
static class SpiceManager.SpiceManagerCommand<T>
           
 class SpiceManager.SpiceServiceConnection
          Reacts to binding/unbinding with SpiceService.
 
Field Summary
protected  BlockingQueue<CachedSpiceRequest<?>> requestQueue
          The queue of requests to be sent to the service.
protected  Thread runner
          Thread running runnable code.
protected static String SPICE_MANAGER_THREAD_NAME_PREFIX
          The prefix of SpiceManager threads (used to send requests to the service).
 
Constructor Summary
SpiceManager(Class<? extends SpiceService> spiceServiceClass)
          Creates a SpiceManager.
 
Method Summary
<T> void
addListenerIfPending(Class<T> clazz, Object requestCacheKey, PendingRequestListener<T> requestListener)
          Add listener to a pending request if it exists.
<T> void
addListenerIfPending(Class<T> clazz, Object requestCacheKey, RequestListener<T> requestListener)
          Deprecated. 
 void addSpiceServiceListener(SpiceServiceListener spiceServiceListener)
           
<T> void
cancel(Class<T> clazz, Object requestCacheKey)
          Cancel a pending request if it exists.
 void cancel(SpiceRequest<?> request)
          Cancel a specific request.
 void cancelAllRequests()
          Cancel all requests.
 void dontNotifyAnyRequestListeners()
          Disable request listeners notifications for all requests.
protected  void dontNotifyAnyRequestListenersInternal()
          Remove all listeners of requests.
 void dontNotifyRequestListenersForRequest(SpiceRequest<?> request)
          Disable request listeners notifications for a specific request.
protected  void dontNotifyRequestListenersForRequestInternal(SpiceRequest<?> request)
          Internal method to remove requests.
 void dumpState()
          Dumps request processor state.
<T> void
execute(CachedSpiceRequest<T> cachedSpiceRequest, RequestListener<T> requestListener)
          Execute a request, put the result in cache and register listeners to notify when request is finished.
<T> void
execute(SpiceRequest<T> request, Object requestCacheKey, long cacheExpiryDuration, RequestListener<T> requestListener)
          Execute a request.
<T> void
execute(SpiceRequest<T> request, RequestListener<T> requestListener)
          Execute a request, without using cache.
protected
<T> Future<T>
executeCommand(SpiceManager.SpiceManagerCommand<T> spiceManagerCommand)
           
 Future<List<Object>> getAllCacheKeys(Class<?> clazz)
           
<T> Future<List<T>>
getAllDataFromCache(Class<T> clazz)
           
<T> Future<T>
getDataFromCache(Class<T> clazz, Object cacheKey)
          Get some data previously saved in cache with key requestCacheKey.
 Future<Date> getDateOfDataInCache(Class<?> clazz, Object cacheKey)
          Returns the last date of storage of a given data into the cache.
<T> void
getFromCache(Class<T> clazz, Object requestCacheKey, long cacheExpiryDuration, RequestListener<T> requestListener)
          Get some data previously saved in cache with key requestCacheKey with maximum time in cache : cacheDuration millisecond and register listeners to notify when request is finished.
<T> void
getFromCacheAndLoadFromNetworkIfExpired(SpiceRequest<T> request, Object requestCacheKey, long cacheExpiryDuration, RequestListener<T> requestListener)
          Gets data from cache, expired or not, and executes a request normaly.
 int getPendingRequestCount()
           
 int getRequestToLaunchCount()
           
protected  int getThreadCount()
          Number of threads used internally by this spice manager to communicate commands to the SpiceService it is bound to
protected  boolean isBound()
          For testing purpose.
 Future<Boolean> isDataInCache(Class<?> clazz, Object cacheKey, long cacheExpiryDuration)
          Tests whether some data is present in cache or not.
 boolean isStarted()
          Method is synchronized with start(Context).
<T> Future<T>
putDataInCache(Object cacheKey, T data)
          Put some new data in cache using cache key requestCacheKey.
<T> void
putInCache(Class<? super T> clazz, Object requestCacheKey, T data)
          Adds some data to the cache, asynchronously.
<U,T extends U>
void
putInCache(Class<U> clazz, Object requestCacheKey, T data, RequestListener<U> listener)
          Adds some data to the cache, asynchronously.
<T> void
putInCache(Object requestCacheKey, T data)
          Adds some data to the cache, asynchronously.
<T> void
putInCache(Object requestCacheKey, T data, RequestListener<T> listener)
          Adds some data to the cache, asynchronously.
 Future<?> removeAllDataFromCache()
          Remove all data from cache.
<T> Future<?>
removeDataFromCache(Class<T> clazz)
          Remove some specific content from cache
<T> Future<?>
removeDataFromCache(Class<T> clazz, Object cacheKey)
          Remove some specific content from cache
 void removeSpiceServiceListener(SpiceServiceListener spiceServiceListener)
           
 void run()
           
 void setFailOnCacheError(boolean failOnCacheError)
          Configure the behavior in case of error during reading/writing cache.
 void shouldStop()
          Stops the SpiceManager.
 void shouldStopAndJoin(long timeOut)
          This is mostly a testing method.
 void start(android.content.Context context)
          Start the SpiceManager.
protected  void waitForServiceToBeBound()
          Wait for acquiring binding to SpiceService.
protected  void waitForServiceToBeUnbound()
          Wait for acquiring binding to SpiceService.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SPICE_MANAGER_THREAD_NAME_PREFIX

protected static final String SPICE_MANAGER_THREAD_NAME_PREFIX
The prefix of SpiceManager threads (used to send requests to the service).

See Also:
Constant Field Values

requestQueue

protected final BlockingQueue<CachedSpiceRequest<?>> requestQueue
The queue of requests to be sent to the service.


runner

protected Thread runner
Thread running runnable code.

Constructor Detail

SpiceManager

public SpiceManager(Class<? extends SpiceService> spiceServiceClass)
Creates a SpiceManager. Typically this occurs in the construction of an Activity or Fragment. This method will check if the service to bind to has been properly declared in AndroidManifest.

Parameters:
spiceServiceClass - the service class to bind to.
Method Detail

getThreadCount

protected int getThreadCount()
Number of threads used internally by this spice manager to communicate commands to the SpiceService it is bound to

Returns:
the thread count. Defaults to DEFAULT_THREAD_COUNT.

start

public void start(android.content.Context context)
Start the SpiceManager. It will bind asynchronously to the SpiceService.

Parameters:
context - a context that will be used to bind to the service. Typically, the Activity or Fragment that needs to interact with the SpiceService.

isStarted

public boolean isStarted()
Method is synchronized with start(Context).

Returns:
whether or not the SpiceManager is started.

getRequestToLaunchCount

public int getRequestToLaunchCount()
Returns:
the number of current requests that should be launched ASAP (when the spice service is bound).

getPendingRequestCount

public int getPendingRequestCount()
Returns:
the number of current request that are currently pending and being processed by the spice service.

run

public void run()
Specified by:
run in interface Runnable

shouldStop

public void shouldStop()
Stops the SpiceManager. It will unbind from SpiceService. All request listeners that had been registered to listen to SpiceRequests sent from this SpiceManager will be unregistered. None of them will be notified with the results of their SpiceRequests. Unbinding will occur asynchronously.


shouldStopAndJoin

public void shouldStopAndJoin(long timeOut)
                       throws InterruptedException
This is mostly a testing method. Stops the SpiceManager. It will unbind from SpiceService. All request listeners that had been registered to listen to SpiceRequests sent from this SpiceManager will be unregistered. None of them will be notified with the results of their SpiceRequests. Unbinding will occur syncrhonously : the method returns when all events have been unregistered and when main processing thread stops.

Throws:
InterruptedException

getFromCache

public <T> void getFromCache(Class<T> clazz,
                             Object requestCacheKey,
                             long cacheExpiryDuration,
                             RequestListener<T> requestListener)
Get some data previously saved in cache with key requestCacheKey with maximum time in cache : cacheDuration millisecond and register listeners to notify when request is finished. This method executes a SpiceRequest with no network processing. It just checks whatever is in the cache and return it, including null if there is no such data found in cache.

Parameters:
clazz - the class of the result to retrieve from cache.
requestCacheKey - the key used to store and retrieve the result of the request in the cache
cacheExpiryDuration - duration in milliseconds after which the content of the cache will be considered to be expired. DurationInMillis.ALWAYS_RETURNED means data in cache is always returned if it exists. DurationInMillis.ALWAYS_EXPIRED means data in cache is never returned.(see DurationInMillis)
requestListener - the listener to notify when the request will finish. If nothing is found in cache, listeners will receive a null result on their RequestListener.onRequestSuccess(Object) method. If something is found in cache, they will receive it in this method. If an error occurs, they will be notified via their RequestListener.onRequestFailure(com.octo.android.robospice.persistence.exception.SpiceException) method.

addListenerIfPending

@Deprecated
public <T> void addListenerIfPending(Class<T> clazz,
                                                Object requestCacheKey,
                                                RequestListener<T> requestListener)
Deprecated. 


addListenerIfPending

public <T> void addListenerIfPending(Class<T> clazz,
                                     Object requestCacheKey,
                                     PendingRequestListener<T> requestListener)
Add listener to a pending request if it exists. If no such request exists, this method calls onRequestNotFound on the listener. If a request identified by clazz and requestCacheKey, it will receive an additional listener.

Parameters:
clazz - the class of the result of the pending request to look for.
requestCacheKey - the key used to store and retrieve the result of the request in the cache
requestListener - the listener to notify when the request will finish.

execute

public <T> void execute(SpiceRequest<T> request,
                        RequestListener<T> requestListener)
Execute a request, without using cache. No result from cache will be returned. The method SpiceRequest.loadDataFromNetwork() will always be invoked. The result will not be stored in cache.

Parameters:
request - the request to execute.
requestListener - the listener to notify when the request will finish.

execute

public <T> void execute(SpiceRequest<T> request,
                        Object requestCacheKey,
                        long cacheExpiryDuration,
                        RequestListener<T> requestListener)
Execute a request. Before invoking the method SpiceRequest.loadDataFromNetwork(), the cache will be checked : if a result has been cached with the cache key requestCacheKey, RoboSpice will consider the parameter cacheExpiryDuration to determine whether the result in the cache is expired or not. If it is not expired, then listeners will receive the data in cache. Otherwise, the method SpiceRequest.loadDataFromNetwork() will be invoked and the result will be stored in cache using the cache key requestCacheKey.

Parameters:
request - the request to execute
requestCacheKey - the key used to store and retrieve the result of the request in the cache
cacheExpiryDuration - duration in milliseconds after which the content of the cache will be considered to be expired. DurationInMillis.ALWAYS_RETURNED means data in cache is always returned if it exists. DurationInMillis.ALWAYS_EXPIRED means data in cache is never returned.(see DurationInMillis)
requestListener - the listener to notify when the request will finish

execute

public <T> void execute(CachedSpiceRequest<T> cachedSpiceRequest,
                        RequestListener<T> requestListener)
Execute a request, put the result in cache and register listeners to notify when request is finished.

Parameters:
cachedSpiceRequest - the request to execute. CachedSpiceRequest is a wrapper of SpiceRequest that contains cache key and cache duration
requestListener - the listener to notify when the request will finish

getFromCacheAndLoadFromNetworkIfExpired

public <T> void getFromCacheAndLoadFromNetworkIfExpired(SpiceRequest<T> request,
                                                        Object requestCacheKey,
                                                        long cacheExpiryDuration,
                                                        RequestListener<T> requestListener)
Gets data from cache, expired or not, and executes a request normaly. Before invoking the method SpiceRequest.loadDataFromNetwork(), the cache will be checked : if a result has been cached with the cache key requestCacheKey, RoboSpice will consider the parameter cacheExpiryDuration to determine whether the result in the cache is expired or not. If it is not expired, then listeners will receive the data in cache only. If the result is absent or expired, then SpiceRequest.loadDataFromNetwork() will be invoked and the result will be stored in cache using the cache key requestCacheKey.

Parameters:
request - the request to execute
requestCacheKey - the key used to store and retrieve the result of the request in the cache
cacheExpiryDuration - duration in milliseconds after which the content of the cache will be considered to be expired. DurationInMillis.ALWAYS_RETURNED means data in cache is always returned if it exists. DurationInMillis.ALWAYS_EXPIRED doesn't make much sense here.
requestListener - the listener to notify when the request will finish

putInCache

public <U,T extends U> void putInCache(Class<U> clazz,
                                       Object requestCacheKey,
                                       T data,
                                       RequestListener<U> listener)
Adds some data to the cache, asynchronously.

Parameters:
clazz - a super class or the class of data.
requestCacheKey - the request cache key that data will be stored in.
data - the data to store. Maybe null if supported by underlying ObjectPersister.
listener - a listener that will be notified of this request's success or failure. May be null.

putInCache

public <T> void putInCache(Class<? super T> clazz,
                           Object requestCacheKey,
                           T data)
Adds some data to the cache, asynchronously. Same as putInCache(Class, Object, Object, RequestListener) with a null listener. Operation will take place but you won't be notified.

Parameters:
clazz - a super class or the class of data.
requestCacheKey - the request cache key that data will be stored in.
data - the data to store. Maybe null if supported by underlying ObjectPersister.

putInCache

public <T> void putInCache(Object requestCacheKey,
                           T data,
                           RequestListener<T> listener)
Adds some data to the cache, asynchronously. Same as putInCache(Class, Object, Object, RequestListener) where the class used to identify the request is data.getClass().

Parameters:
requestCacheKey - the request cache key that data will be stored in.
data - the data to store. Maybe null if supported by underlying ObjectPersister.
listener - a listener that will be notified of this request's success or failure. May be null.

putInCache

public <T> void putInCache(Object requestCacheKey,
                           T data)
Adds some data to the cache, asynchronously. Same as putInCache(Class, Object, Object, RequestListener) where the class used to identify the request is data.getClass() and with a null listener. Operation will take place but you won't be notified.

Parameters:
requestCacheKey - the request cache key that data will be stored in.
data - the data to store. Maybe null if supported by underlying ObjectPersister.

cancel

public <T> void cancel(Class<T> clazz,
                       Object requestCacheKey)
Cancel a pending request if it exists. If no such request exists, this method does nothing. If a request identified by clazz and requestCacheKey exists, it will be cancelled and its associated listeners will get notified. This method is asynchronous.

Parameters:
clazz - the class of the result of the pending request to look for.
requestCacheKey - the cache key associated to the request's results.

dontNotifyRequestListenersForRequest

public void dontNotifyRequestListenersForRequest(SpiceRequest<?> request)
Disable request listeners notifications for a specific request.
None of the listeners associated to this request will be called when request will finish.
This method will ask (asynchronously) to the SpiceService to remove listeners if requests have already been sent to the SpiceService if the request has already been sent to the service. Otherwise, it will just remove listeners before passing the request to the SpiceService. Calling this method doesn't prevent request from being executed (and put in cache) but will remove request's listeners notification.

Parameters:
request - Request for which listeners are to unregistered.

dontNotifyRequestListenersForRequestInternal

protected void dontNotifyRequestListenersForRequestInternal(SpiceRequest<?> request)
Internal method to remove requests. If request has not been passed to the SpiceService yet, all listeners are unregistered locally before being passed to the service. Otherwise, it will asynchronously ask to the SpiceService to remove the listeners of the request being processed.

Parameters:
request - Request for which listeners are to unregistered.

dontNotifyAnyRequestListeners

public void dontNotifyAnyRequestListeners()
Disable request listeners notifications for all requests.
Should be called in Activity.onStop()


dontNotifyAnyRequestListenersInternal

protected void dontNotifyAnyRequestListenersInternal()
Remove all listeners of requests. All requests that have not been yet passed to the service will see their of listeners cleaned. For all requests that have been passed to the service, we ask the service to remove their listeners.


cancel

public void cancel(SpiceRequest<?> request)
Cancel a specific request. Synchronous.

Parameters:
request - the request to cancel

cancelAllRequests

public void cancelAllRequests()
Cancel all requests. Asynchronous.


addSpiceServiceListener

public void addSpiceServiceListener(SpiceServiceListener spiceServiceListener)

removeSpiceServiceListener

public void removeSpiceServiceListener(SpiceServiceListener spiceServiceListener)

getAllCacheKeys

public Future<List<Object>> getAllCacheKeys(Class<?> clazz)

getAllDataFromCache

public <T> Future<List<T>> getAllDataFromCache(Class<T> clazz)
                                    throws CacheLoadingException
Throws:
CacheLoadingException

getDataFromCache

public <T> Future<T> getDataFromCache(Class<T> clazz,
                                      Object cacheKey)
                           throws CacheLoadingException
Get some data previously saved in cache with key requestCacheKey. This method doesn't perform any network processing, it just checks if there are previously saved data. Don't call this method in the main thread because you could block it. Instead, use the asynchronous version of this method: getFromCache(Class, Object, long, RequestListener).

Parameters:
clazz - the class of the result to retrieve from cache.
cacheKey - the key used to store and retrieve the result of the request in the cache
Returns:
a future object that will hold data in cache. Calling get on this future will block until the data is actually effectively taken from cache.
Throws:
CacheLoadingException - Exception thrown when a problem occurs while loading data from cache.

putDataInCache

public <T> Future<T> putDataInCache(Object cacheKey,
                                    T data)
                         throws CacheSavingException,
                                CacheCreationException
Put some new data in cache using cache key requestCacheKey. This method doesn't perform any network processing, it just data in cache, erasing any previsouly saved date in cache using the same class and key. Don't call this method in the main thread because you could block it. Instead, use the asynchronous version of this method: putInCache(Class, Object, Object).

Parameters:
cacheKey - the key used to store and retrieve the result of the request in the cache
data - the data to be saved in cache.
Returns:
the data has it has been saved by an ObjectPersister in cache.
Throws:
CacheLoadingException - Exception thrown when a problem occurs while loading data from cache.
CacheSavingException
CacheCreationException

isDataInCache

public Future<Boolean> isDataInCache(Class<?> clazz,
                                     Object cacheKey,
                                     long cacheExpiryDuration)
                              throws CacheCreationException
Tests whether some data is present in cache or not.

Parameters:
clazz - the class of the result to retrieve from cache.
cacheKey - the key used to store and retrieve the result of the request in the cache
cacheExpiryDuration - duration in milliseconds after which the content of the cache will be considered to be expired. DurationInMillis.ALWAYS_RETURNED means data in cache is always returned if it exists. DurationInMillis.ALWAYS_EXPIRED means data in cache is never returned.(see DurationInMillis)
Returns:
the data has it has been saved by an ObjectPersister in cache.
Throws:
CacheCreationException - Exception thrown when a problem occurs while looking for data in cache.

getDateOfDataInCache

public Future<Date> getDateOfDataInCache(Class<?> clazz,
                                         Object cacheKey)
                                  throws CacheCreationException
Returns the last date of storage of a given data into the cache.

Parameters:
clazz - the class of the result to retrieve from cache.
cacheKey - the key used to store and retrieve the result of the request in the cache
Returns:
the date at which data has been stored in cache. Null if no such data is in Cache.
Throws:
CacheLoadingException - Exception thrown when a problem occurs while loading data from cache.
CacheCreationException

removeDataFromCache

public <T> Future<?> removeDataFromCache(Class<T> clazz,
                                         Object cacheKey)
Remove some specific content from cache

Parameters:
clazz - the Type of data you want to remove from cache
cacheKey - the key of the object in cache

removeDataFromCache

public <T> Future<?> removeDataFromCache(Class<T> clazz)
Remove some specific content from cache

Parameters:
clazz - the type of data you want to remove from cache.

removeAllDataFromCache

public Future<?> removeAllDataFromCache()
Remove all data from cache. This will clear all data stored by the CacheManager of the SpiceService.


setFailOnCacheError

public void setFailOnCacheError(boolean failOnCacheError)
Configure the behavior in case of error during reading/writing cache.
Specify wether an error on reading/writing cache must fail the process.

Parameters:
failOnCacheError - true if an error must fail the process

dumpState

public void dumpState()
Dumps request processor state.


isBound

protected boolean isBound()
For testing purpose.


waitForServiceToBeBound

protected void waitForServiceToBeBound()
                                throws InterruptedException
Wait for acquiring binding to SpiceService.

Throws:
InterruptedException - in case the binding is interrupted.

waitForServiceToBeUnbound

protected void waitForServiceToBeUnbound()
                                  throws InterruptedException
Wait for acquiring binding to SpiceService.

Throws:
InterruptedException - in case the binding is interrupted.

executeCommand

protected <T> Future<T> executeCommand(SpiceManager.SpiceManagerCommand<T> spiceManagerCommand)


Copyright © 2012-2014. All Rights Reserved.