-
Notifications
You must be signed in to change notification settings - Fork 545
Starter guide
You wanna see what RoboSpice looks like in action ? Great ! This is the page you are looking for.
This document is a tutorial to implement RoboSpice using the Spring Android module. It will :
- perform a REST request to a web service (e.g. Tweeter API);
- convert JSON results to POJOs ;
- cache them on disk ;
- let you control cache expiry ;
- notify you app, on the UI thread, when result is ready.
To use RoboSpice in your application, there are 4 steps :
-
Use a pre-set
SpiceService
or Create aSpiceService
: this step has to be performed once for all requests ; - Spice your activity : this step has to be repeated for each Activity class (or only once for your project if you use a common base class for all your activities) ;
-
Create a
SpiceRequest
and aRequestListener
: those 2 steps have to be repeated for each request to a web service. - Of course, you also need to Define POJO classes` to get a Java representation of the results of the requests.
Please, note that the snippets in this page are excerpts of the Spring Android sample of Robospice.
Release 1.4.0 of RoboSpice allows to use pre-set SpiceServices
instead of creating your own SpiceService
.
For instance if you want to use Spring Android to both parse the results of your JSON network requests into POJOs, and cache the resulting POJOs using JSON on disk, simply add the following line to your AndroidManifest.xml
file :
<service
android:name="com.octo.android.robospice.JacksonSpringAndroidSpiceService"
android:exported="false" />
You can now jump directly to the section Spice your activity, or read below if you want to learn how to create a custom SpiceService
.
This part is the most difficult, but you only have to do it once to enable all requests to be processed.
You will define a subclass of SpiceService
and declare it in the AndroidManifest.xml
file.
public class JsonSpiceService extends SpringAndroidSpiceService {
@Override
public CacheManager createCacheManager( Application application ) {
CacheManager cacheManager = new CacheManager();
JacksonObjectPersisterFactory jacksonObjectPersisterFactory = new JacksonObjectPersisterFactory( application );
cacheManager.addPersister( jacksonObjectPersisterFactory );
return cacheManager;
}
@Override
public RestTemplate createRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
//find more complete examples in RoboSpice Motivation app
//to enable Gzip compression and setting request timeouts.
// web services support json responses
MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter();
FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
final List< HttpMessageConverter< ? >> listHttpMessageConverters = restTemplate.getMessageConverters();
listHttpMessageConverters.add( jsonConverter );
listHttpMessageConverters.add( formHttpMessageConverter );
listHttpMessageConverters.add( stringHttpMessageConverter );
restTemplate.setMessageConverters( listHttpMessageConverters );
return restTemplate;
}
Then add this to your AndroidManifest.xml
file :
<service
android:name="<your package>.JsonSpiceService"
android:exported="false" />
In your activity, or a base class if you use one (preferred), add the following :
private static final String JSON_CACHE_KEY = "tweets_json";
private SpiceManager spiceManager = new SpiceManager( JsonSpiceService.class );
@Override
protected void onStart() {
super.onStart();
spiceManager.start( this );
}
@Override
protected void onStop() {
spiceManager.shouldStop();
super.onStop();
}
public void refreshTweets() {
spiceManager.execute( new TweetJsonRequest(), JSON_CACHE_KEY, DurationInMillis.NEVER, new TweetRequestListener() );
}
In the example above, you can see that the third argument passed to the execute()
method is the constant
DurationInMillis.NEVER
. Use this parameter to specify when data will be taken from the cache
without invoking retrieval of new data from the network.
If you pass a long value, then it represents the
maximum accepted age in milliseconds of cached data that a SpiceManager
will accept.
The constant DurationInMillis.ALWAYS
used in the above
example indicates that the client never considers a data in cache as expired, regardless of how recent it is.
Data in cache will always be returned, a network call will only be made once.
There is also a constant named DurationInMillis.NEVER
which means that the data in cache will always be considered expired, regardless of how recent it is. Thus, the SpiceRequest
will always perform a network call, and you will never get the data in cache.
There are also constants that represent common time durations, such as DurationInMillis.ONE_HOUR
and
DurationInMillis.ONE_WEEK
provided as helpers to write durations in milliseconds (i.e. 4 * DurationInMillis.ONE_MINUTE
).
You will repeat this step for each different kind of request. Those steps are easy and intuitive :
//in its own Java file
public class TweetJsonRequest extends SpringAndroidSpiceRequest< ListTweets > {
public TweetJsonRequest() {
super( ListTweets.class );
}
@Override
public ListTweets loadDataFromNetwork() throws Exception {
return getRestTemplate().getForObject( "http://search.twitter.com/search.json?q=android&rpp=20", ListTweets.class );
}
}
As an inner class of your Activity
, add a RequestlListener
that will update your UI.
Don't worry about memory leaks, RoboSpice manages your activity life cycle.
//inner class of your spiced Activity
private class TweetRequestListener implements RequestListener< ListTweets > {
@Override
public void onRequestFailure( SpiceException spiceException ) {
//update your UI
}
@Override
public void onRequestSuccess( ListTweets listTweets ) {
//update your UI
}
}
Both methods will be executed inside the UI thread, RoboSpice handles this for you.
In this example, we used the following POJOs to receive a list of Tweets using Json via Jackson :
@JsonIgnoreProperties(ignoreUnknown = true)
public class ListTweets {
private List< Tweet > results;
public List< Tweet > getResults() {
return results;
}
public void setResults( List< Tweet > results ) {
this.results = results;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Tweet {
private String text;
public String getText() {
return text;
}
public void setText( String text ) {
this.text = text;
}
}
You're done ! Launch your activity, plug the refreshTweets()
method to a Button
in your Activity
, and enjoy !