We have been using Robospice framework for quite long time for developing mobile apps based on android platform. Though robospice is excellent framework to handle asynchronous tasks(better than AsyncTask and Loader) and support many frameworks but we need to write a lot of boiler plate code. Sometimes it becomes too big and complex that a developer get confused e.g. For writing a simple network request source code, a developer needs to do:
- Write a SpiceRequest (which is a basic RoboSpice object that performs the actual background task).
- Write a RequestListener instances( which are basic RoboSpice objects that will get notified of the processing of a SpiceRequest)
- Need to create SpiceManager(is a basic RoboSpice object that executes requests).
Recently we had to start working on new android mobile app which required extensive use of the REST API. RoboSpice would have been our first choice but we gave a try to use some other framework. Then we found android AsyncService which nearly resolved our problem. It is very good alternative to Robospice which makes our code short and simple. It manages threading and caching transparently in the Android app.
We tried to find the AsyncService framework example which uses network request but could not find any. So we decided to write an example which uses AsyncService, Spring for android and Picasso. In this article we are demonstrating a sample application which gets the user list from github REST API.
How to use android AsyncService in our application
Just add this line to your gradle dependencies:
'com.joanzapata.android.asyncservice:android-asyncservice:0.0.5@aar') { transitive = true }
Structure of the android AsyncService
- Service – It is the class in which you define your REST API ( write an asynchronous service).
@AsyncService public class GithubService { private User getUser(String name) { // Runs asynchronously. String url =""; // web services support json responses // here write your logic for network call MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter(); FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter(); StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); List listHttpMessageConverters = new ArrayList<HttpMessageConverter>(); listHttpMessageConverters.add( jsonConverter ); listHttpMessageConverters.add( formHttpMessageConverter ); listHttpMessageConverters.add( stringHttpMessageConverter ); RestTemplate restTemplate = new RestTemplate(); restTemplate.setMessageConverters(listHttpMessageConverters); //send other parameters Map<String, Object> queryParams = new HashMap<String, Object> queryParams.put(key,value); queryParams.put(key,value); // build your url UriComponentsBuilder baseUriComp = UriComponentsBuilder .fromUriString(url); for (Map.Entry<String, Object> entry : queryParams.entrySet()) { baseUriComp.queryParam(entry.getKey(), entry.getValue()); } url = baseUriComp.build().toUriString(); return restTemplate.getForObject(url,User.class); } } // For caching use the following method @CacheThenCall(validity = CACHE_TIME,value="GithubService.getUserFromCache({name})") public User getUserFromCache(String name){ return getUser(name); }
Here CACHE_TIME will be defined according to your need to cache your data . The key value i.e ‘name’ in this case should be unique because it is the unique value which maps the cache key for each data. It can be any unique value created by you with the data values.
- Model – This is the class where you write our Response class object for the defined request.
- MainActivity – It is the main class in which your defined request is called and all the other stuff are done.
public class MainActivity extends FragmentActivity { public static final String TAG = "MainActivity"; private TextView UserName; @InjectService public static GithubService service; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AsyncService.inject(this); setContentView(R.layout.event_list); service.getUserFromCache(""); } @OnMessage public void onUserFetched(User e) { UserName=(TextView) findViewById(R.id.text1); UserName.setText(e.getName()); } }
Add the following entries in your proguard configuration file:
-dontwarn com.joanzapata.android.asyncservice.**
-keep @com.joanzapata.android.asyncservice.api.annotation.AsyncService class *
-keep class **Injector
-keepnames class **Injector
-keepnames class * {
@com.joanzapata.android.asyncservice.api.annotation.InjectService *;
}
-keepnames class * {
@com.joanzapata.android.asyncservice.api.annotation.OnMessage *;
}
-keep class com.esotericsoftware.kryo.** {*;}
Magic Tips to learn while while using android AsynService in your application:
- Method called for caching should always be public whereas the other methods are private.
- “Key” value in cache method should be unique.
- “@OnMessage” method should always be public.
- There should always be only one “@OnMessage” method with same parameters in a class.
Sample Source Code
For the complete code click here .
Conclusion
Android AsyncService is not only easy to use but also very simple to write and understand.It manages cache in very efficient way and have a very less possibilities of memory leaks. It increases the responsiveness of the application because the view is immediately filled with cached data, so most of the time the user doesn’t have to wait. Then, when the up-to-date result arrives from the server, the displayed information is replaced .
References