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}).*
Related
What is the best way to make a deferred simple okhttp3 web request like:
Request request = Request.Builder().url(url).post(body).build();
Response response = client.newCall(request).execute();
that gets executed as soon as a client goes online and only then to handle result?
For example, client makes change to the data locally and this change should be posted on server. But there are cases when user does it offline, but we still have to handle it.
You can use a broadcast receiver which listen for internet connectivity changes, and Deferred library for deferring the request Jdeferred.
If use of deferred is too much work and overkill, You can use a conutdownlatch and
wait on separate thread until, the connectivity change, but the wait time can be huge, so chose wisely.
You can also consider CompletableFuture. But this is available from api 24 only
Let me know if you need more clarification.
I'm using Volley as network library on Android. I ran into 'limited functionality' problems when using ImageLoader. It seems to be quite useful class with caching and stuff, so I want to continue using it. However, it doesn't give any access to the Request objects it creates. As a result, I'm not able to do some stuff that I can do in other cases (like setting a tag on the request for cancelling it from queue).
My current problem is - how can I set a retry policy on requests made using ImageLoader?
I think there is no way to set retry policy for ImageLoader. But you have access to all requests through volley singleton (if you use one). Try to change retry policy in addToRequestQueue method. If you need different retry specification for images and other requests - you can simply create two request queues (bad practice).
I have 2 class of AsyncTask for handling request one for sync and other class for handling other request but when I send sync request and move to other page and request response for second request will get after sync request responds. How I solution this?
Hope any one help me
Basically you can use Volley
Volley offers the following benefits:
Automatic scheduling of network requests.
Multiple concurrent network connections.
Transparent disk and memory response caching with standard HTTP
cache coherence.
Support for request prioritization.
Cancellation request API. You can cancel a single request, or you
can set blocks or scopes of requests to cancel.
Ease of customization, for example, for retry and backoff.
Strong ordering that makes it easy to correctly populate your UI
with data fetched asynchronously from the network.
Debugging and tracing tools.
You can easily find a tutorial for it and
It much faster then AsyncTask .
For reference check this
You can make asyntask run parallel execution by replacing execute() with executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).
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.
I am starting to use robospice for an application which has to function in regions with changing connectivity.
How would I achieve that robospice would automatically return the cached data when the network is down?
Thanks
Ben
I have not worked with Robospice at all. But from what I can tell it looks like the request class allows you to specify AcceptingDirtyCache by calling
request.setAcceptingDirtyCache(boolean isAcceptingDirtyCache)
there was a thread about this on github that talks about this very problem.
Also not sure since I have never used robospice but you should be able to call CacheManager.loadDataFromCache() to load any data that exists in the cache. So you could utilize this function whenever you need to make a request but the network is down.