Robospice/ Retrofit background service accessing database - android

I've successfully created a Retrofit API Rest client making both GET & POST calls and also incorporated that into Robospice as a background service.
However, I want the Robospice service to connect to the database and asynchronously persist the retrieved objects from the GET call. Using the Retrofit Callback class seems the obvious way but connecting to the database requires Context and I"m concerned about leaking the Context.
so, what would be the best approach to get the Robospice SpiceService to persist data to the database both prior to and post a request being processed?

Your question is really fuzzy to me. I don't understand why you can't use the normal persistence mechanism of RS. If you do so, it's pretty easy to persist your data when requests have been executed.
Maybe I am missing something. So, if your requirement is really to persist data yourself, then the approach you propose looks right. You could inject the spice service itself inside your request (see how addRequest is override in RetrofitSpiceService for instance). The request would then hold a context that can be used for persistence inside a callback, or inside the request itself.
Recently I have coded a POST request using retrofit and RS. I changed the signature of the POST request to return a Void. Then slightly modified the retrofit converter to deal with that case and return null. The request received the spice service via injection as mentioned earlier and could do some actions on the database.
Here is some code to inject the application inside a request from within a spice service.
#Override
public void addRequest(CachedSpiceRequest<?> request,
Set<RequestListener<?>> listRequestListener) {
if (request.getSpiceRequest() instanceof MySpiceRequest) {
MySpiceRequest<?> mySpiceRequest = (MySpiceRequest<?>) request
.getSpiceRequest();
mySpiceRequest.setApplication(this.getApplication());
}
super.addRequest(request, listRequestListener);
}

In the end, as I'm batching the various Rest API service calls to save radio (Reto Meier Dev Bytes: Efficient Data Transfers), I call the Rest API services (RetrofitSpiceServices) from within a controller Robospice SpiceService containing both the reference to the DatabaseHelper (requiring Context) and the respective Retrofit callbacks for the Rest services.
This way, the controller service handles all the triggering (AlarmManager triggers the controller service) and persisting to DB and the Rest services can shut themselves down as normal without knowledge of context, database or suchlike.
For #lion789:
I have 4 models each with a corresponding API call to sync with the server (1 POST, 3 GET).
To handle these sync calls, I have an IntentService that contains 4 SpiceManager attribute and 4 Retrofit Callback classes - one for each model/API call.
The IntentService is passed an Enum indicating a sequence of APIs that should be called.
The IntentService calls the appropriate SpiceManager which runs, then the Callback triggers the persistence and calls an IntentService method to trigger the next API call in the sequence.
A lot of this is abstracted and interfaced as I use it for my Auth and Push Registration code so it's a bit of a nightmare to describe but it's been working pretty well thus far.

Related

Is there any methods to keep calling API and fetch the latest data using Retrofit in Android?

I am creating an app which is like queue displaying. For my scenario, the queue data is always updating. Is there any method that enable I efficiently calling API to get latest data, beside using Handler. Using Handler, might can solve my issue but it's not a good practise because keep calling API for every 5 seconds, might causing server overload/ memory issue? Btw, the API is restful API.
You can implement RxJava with Retrofit such that the Retrofit Service is called every x seconds in your Android Application.
RxJava - is a Java VM implementation of ReactiveX a library for
composing asynchronous and event-based programs by using observable
sequences
In order to create a Retrofit service that runs after certain time intervals, we can use the following :
Handlers (are used to pass data from the background thread to the UI thread)
RxJava
Using RxJava we can do much more than that and very easily as well, using RxJava operators.
We can use the interval operator to call a certain method ( retrofit network call in this case) after every given period.
Observable.interval operator is used to emit values after certain intervals. It looks like this:
Observable.interval(1000, 5000,
TimeUnit.MILLISECONDS);
1000 is the initial delay before the emission starts and repeats every 5 seconds.
We can subscribe our observers which would call the Retrofit method after every 5 seconds.
Calling Retrofit service after certain intervals is fairly common in applications that provide live updates, such as Cricket Score application, etc.
For more details,
Basics of RxJava and Retrofit together
Android Retrofit call every x seconds
I understand you need to update the data when there is the latest data on the server.
I think you need to apply Socket.io for server and client. When the server has new data, it will notify the client through the socket.
Method 1: When the server sends the event to the client, it will send the latest data.
Method 2: When the client receives the event, it will call the API to get the latest data.
This is advisable because when the number of users is very large, it will save resources.
I used to have a problem like yours and found it a bad thing to have clients calling APIs all the time.
Another way is that when the user clicks or manipulates you will call the API to update the data, but this is not recommended

Can we chain multiple API calls or keep track of multiple calls being made at once?

I have 21 API calls that need to be made once the app gets to the splash screen. What my app does is as follows:
a> Make API call using retrofit's enqueue method.
b> once the response is available(call success) it stores data to local database using greendao. Inside app it only uses data from greendao databases. What I need is to keep track of the api call whether it failed or not. If failed retry. Also if there is a way to chain the requests can anyone mention them? I looked into rxjava which allows chaining upto 2 or 3 apis (as far as I know). Any help is much appreciated.
You can create IntentService which will run call.execute() code one by one.
This way you will call synchronous call to all apis.
Once all request completes send broadcast to activity or communicate with activity through other mechanism.

Receiving responses in Android from a Spring REST service

I'm working with Android on the front end and I'm using Spring's REST Client libraries to send HTTP Requests to a REST web service. I've read examples online where people use AsyncTask to accomplish this with a RestTemplate in doInBackground method of AsyncTask, but I've also read examples where RestTemplate is used outside of AsyncTask, even in an activity or fragment. Is there any point in using one method over the other?
Secondly, when receiving a response from the server through RestTemplate's exchange or getForAllObject, based on the data received my client should be doing different things. For example, if I want to search for users, I should receive User objects and then my client should then update the users fragment/activity, but if I want to login, I should receive different data and my client should perform different subsequent tasks.
If I create an AsyncTask every time I send an HTTP Request and then receive the response, how can I distinguish what subsequent tasks need to be done client-side? Is the preferred method to use enums? For eg., when I want to get data from a server, I can instantiate an AsyncTask and pass as execute parameters an enum to specify which HTTP request to send and an enum to specify what to do with received data. Then I could just use switch statements which call different functions based on the enum?
If none of this makes sense, is there a more standard way to approach handling responses from the server?
From docs
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
AsyncTask provides a convenient way to do tasks in background and interact with the main UI thread. If you did not use AsyncTasks you have to implement your own methods to synchronize with the main thread to update the UI. If you are calling any back end services or doing long running operations, it is always good to go with async tasks.
It is a bad practice to have your same REST end point to return different objects based on an enum. Have two separate endpoints. One GET call to search users and one POST call to login users. In the client side also have separate implementations on consuming above endpoints. Use them appropriately when needed.

Enabling Caching for REST requests in Robospice with Jackson and Spring

I have an android app using Robospice with Jackson + Spring to perform REST requests. This is working, except that Robospice doesn't seem to be caching the responses. I've also made sure that the cache key is consistent between requests.
I'm setting up the SpiceManager like this:
private SpiceManager mRestManager = new SpiceManager(JacksonSpringAndroidSpiceService.class);
Then, I'm executing the request like this:
mRestManager.execute(customSpiceRequest, requestCacheKey,
DurationInMillis.ALWAYS, new CustomRequestListener())
I don't know if it's relevant, but my customSpiceRequest extends SpringAndroidSpiceRequest. I've made certain that requestCacheKey is identical between requests too.
Is there something else I need to do to enable caching between requests?
Indeed, RoboSpice is doing what you are asking for : you pass
DurationInMillis.ALWAYS as a parameter to execute.
This means that the data
in cache will always be considered expired. Thus, the SpiceRequest will
always perform a network call. You should just use a different
cacheDuration value when invoking execute.
Since then, Javadoc has been enhanced :
cacheExpiryDuration : duration in millisecond after which the content of the cache will be considered to be expired. For instance DurationInMillis.ALWAYS means that data in cache will always be considered expired, thus requests will always perform their network operations to get new data. DurationInMillis.NEVER means data will never be considered as expired, requests will never perform network operations to refresh data but will always return cached data. (see {#link DurationInMillis}).*

Google IO 2010 Rest Structure

I am looking to implement the Google IO Rest Structure part A - Using a Service API. So i have identified the following portions of the structure.
An interface that provides rest method.
A Processor Class that implements the above interface. There will
many processor Classes. Each Processor class will return a model
class type.
A Service Provider, that deals with a Single Processor. The data
returned from the Processor is handled by the Service Provider. This
will call the Processor Function, and obtain the data returned.
A SerivceProcessor that is a service class. There will be a
single class in the application. This will communicate with the
various SericeProvides based on the Bundle data passed to it.
Service helper that provides high level integration between the
Activity and the Service
Now i am not clear here. The Service has the data that has been requested. How to proceede further. How do i pass the data back from the Service to the ServicHelper. Put it in a Bundle with the tag BUNDLE_EXTRA ? For this my pojo would have to be either Serializable or Parceable. I know Serializable is a really bad option on the Android Platform. What other options are they. Would i be using a Broadcast Intent ?
Thanks for any help here.
You can do a couple of things.
notifying back to the service helper through intents (letting it implement a broadcast receiver). This might be a bad idea since with a single rest call you can get a lot of rows. In this case you should implement some sort of facility to put your pojos in the intents you are sending back (like a fillIntent/getFromIntent method)
inside the service provider, store the result data somewhere (sqllite, contentprovider, file) and just throw a broadcast intent that will contain only the requestId and the result of your call.
The service helper intercept the broadcast and notifies any interested activity that the request has been completed. The activity updates the ui according to that. In this case the servicehelper is used just to keep track of the ongoing request / notify the results.
In my opinion this approach is better because you keep the ui and the model separated, and you don't demand to the activity the storage of the data, and it's more "rest oriented".
Plus: some time ago I tried to implement this approach. It's not completed but you can check the service helper and the request / result intents here postman lib
A more mature and robust library is robospice, which is what I would use now if I had to deal with rest services.

Categories

Resources