Robospice/ Retrofit background service accessing database
Asked Answered
E

2

8

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?

Exemplify answered 25/9, 2013 at 22:25 Comment(0)
E
2

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.

Exemplify answered 7/10, 2013 at 4:11 Comment(5)
Hey do you have an examples of this... I am actually trying to use Robospice as well to cache the data with RetrofitLamothe
Edited my answer to provide more info for @Lion789. Let me know if you need further info.Exemplify
thanks, was actually curious, if I have okHttpClient and retrofit, does the caching happen automatically meaning I do not need to use Robospice then?Lamothe
@lion789 not too sure what you mean by caching. If you're talking about persisting sync data in the DB, I'm rolling my own DatabaseHelper not the Robospice one. If you're going that way, look at OrmLite from which the Robospice database helper inherits. If you're talking about response caching (in a local file), that can be done just via Retrofit (see Jesse Wilson's gist gist.github.com/swankjesse/5889518)Exemplify
Oh ok thanks, yeah I meant response caching... and I have to play around with jesse's response because it was not working... but someone told me it was automatically cached if you just have the two libs and specify it in the headers of the request calls in retrofit... that is why I was not sureLamothe
F
2

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);
    }
Flaunch answered 11/10, 2013 at 8:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.