For my Android app, I want to keep the network traffic as low as possible (of course).
I'm aware of HttpResponseCache but it only works on API >= 13 so it's not an option for me.
I thought of of using using the LruCache, use the REST Url as the key (given theres no POST data).
When I get a response from the server (JSON) I instantly create POJOs from it with Gson.
What's better to use as the value? The JSON String, then deserialize it again with Gson or to store the POJOs? I know deserializing takes a little cpu time, but perhaps there's a downside to storing the POJOs in my cache?
Say I have an Activity that diplays the content of a POJO called 'Product' (that I got from the server as JSON). On orientation change, can I just forget about keeping the Product POJO (via savedInstanceState or whatever) because the network call to retrieve it again will most probably be 'free' anyway (because it's still in the cache)?
Would it be better to have separate caches for different types of Objects or just use one big cache?
Any advise on how to determine a good size for the cache (in MiB or just number of Entries)
A good place to start is Virgil Dobjanschi's Google I/O 2010 talk on RESTful patterns for Android: http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
In a nutshell, he advocates for using SQLite to keep track of the state of your HTTP requests and caching data to minimize requests. I found a sample implementation here, but you may want to search around for more resources on the patterns outlined in that talk.
Since originally answering this, several good open source libraries for Android that will handle caching HTTP requests have come into existence. OkHttp and Volley are two of solid options.
Related
For better UX mobile apps store data on the client side (on the device) to provide immediate information when loading an app without having to wait for data from the internet and providing data even when the device is offline. Of course data is updated/fetched whenever possible later on.
I am building an app (in flutter) which is a social network/information feed like app: there are users, profiles, feed, posts etc. When the user opens the app I would like to show data that was available the last time the app ran.
My question is what is the right way to implement cache? There are two main ways I can think of, an easier/uncertain way and a more difficult/stable way, and I would like your opinion about them. I have time/resource constraints ofc. Most information is through HTTP requests, so:
The easier way: HTTP Cache interception
I would use an out-of-the-box cache plugin for my HTTP client. I think I can just cache the response for each request I make (for some time) and rely on the cached info. Images are also cached based on url. When I make a request on application load I return the cached result if there's any, and if it was a cache hit I fire the request again, so when you open the app you will see immediate information, but after a sec or so you will get the fresh data too. Usability of this solution ofc depends on how well I design my API.
Harder: Store data in a structured database.
This is the option I try to avoid, because it's more time implementing this. It could be either a SQL or document store, and I would have to implement the cache look up/save/update mechanism. Since I am just building the app, I think this would slow me down because data types/ architecture might still change. But is this the ultimate way to go with mobile side caching?
Thank you
I think the easier way is your best bet the only time i can think of that cache could be a problem is if you need critical data that has to be correct and not a old cache value, but you can avoid this problem by not caching the critical values.
Also if you use firebase it does some automatic caching which might be useful.
I looked into solving the problem of accessing data offline in Android and came across Room library and HTTP cache-control. I already have all of the Retrofit / OkHttp responses done in my app. Which is better to implement when there is no Internet connection?
It greatly depends on the requirements of your app.
Room allows you to save and organise the data. Specific queries and extraction of distinct objects is very powerful if needed. Besides that you can be sure the data won't be deleted, when the device needs storage and clears the cache folders. One problem however is data integrity, which would require some sort of synchroniser between your app and the backend server. I would advise you to use Room if you do any sort of data manipulation and/or want to offer certain and reliable offline user experience.
HTTP CACHE is simpler and a quite straightforward solution. You only need to add a interceptor to your OkHttp client and you are ready to go. This would be the solution if you app's main purpose is simply displaying data.
Here is one design/ best practices question..
I'm new to android development, and basically new to web/mobile solutions.
So, my question is - what are best practices when organizing structure of android application that get data from the remote server?
Should request to server go into one class that does communication with server (get and post requests), or should I look at my requests as data source, meaning that every data class manages it for itself?
or should I have more levels of abstraction - one level for acquiring data, other for model that uses some interfaces without knowing from what source data come from?
I'm curious how experienced android developers approach to these design issues...
Virgil Dobjanschi presentation is a good resource as pointed earlier, which basically tells you to run your requests from a background service so the activity does not get destroyed and to store your data in the database as early as possible.
For more technical details, the way I am doing it is to divide the app into three components:
1- Library to encapsulate the handling of the HTTP request and response (with ApacheHTTP), which can handle simple request/response and advanced features that might involve cookies (can be necessary for login) and modifying the HTTP header.
2- Marshal/Unmarsha layer, where I parse the server data (e.g. XML or JSON) and convert it to objects (i.e. models) that the rest of my app will deal with.
3- Persistence layer.
As per Dobjanschi's presentation, I usually make data requests run in a service not in a thread worker inside the activity.
Use one of the 3 models presented at this Google I/O talk. It provides you suggestions that will help you out on the whole process of definition of your app architecture. It'll also prevent you from making common mistakes beginners use to make:
http://www.youtube.com/watch?v=xHXn3Kg2IQE
This post will also help you out:
Need sample Android REST Client project which implements Virgil Dobjanschi REST implementation pattern
My client is an Android app and my service is an asp.net web api. I’m the only one using my service. I am trying to duplicate, in the Android-REST world what I am already doing in the Microsoft Windows Phone 7/ WCF SOAP world. I have numerous methods that both receive complex objects and return complex objects.
The WCF-SOAP world is simple. You can pass any complex arguments you want and return any complex results you want. Logically, it’s just a Remote Procedure Call.
But when I post questions about doing the same thing in REST, I’m told I should limit my services into GET, PUT, POST, and DELETE only. And that I should only do what is “proper” according to RFC2616. Some speak of this in almost a religious manner.
Forgeting about the religion, what’s wrong with using a GET for everything? Or what’s wrong with using a POST for everything? What I do does not fall into the simplistic RFC2616 categories. For instance I’m passing a thousand legs of a trip taken in a car and I’m getting back another version of that trip with erratic GPS errors smoothed out. Or, I’m sending a conversation in english and getting that conversation back in German.
In the android client I have the objects I want to send over HTTP already serialized into json strings by using Google-GSON. So my questions are…
How can I send these json strings to my REST Service as arguments in either GET or POST?
Is it possible and feasible to use just all GETs (or all POSTs) for all of my calls to my REST Service and how do I do that?
I have a more pragmatic question about this posted at sending a json string in a http url as I can’t find any examples anywhere of sending json strings over http GET or POST.
Thanks, Gary
Using the good HTTP verb is very usefull to simply know what to do when you request failed (for example) or just to do some specific stuff. If you sent a POST request, it's implicitly suppose that you have to parse your resource in order to obtain a stream which be sent via the request's body. In other hand, when you are retrieving data via GET, it's suppose that the request is gonna be sent back to you as a stream that you will mapped to your model, pojo, or anything else.
I can suggest you to use library such as RESTDroid. You can send POJO and receive POJO. It's a "resource oriented" library, so you can know at any moment if a particular local resource is remotely syncronized. Data persistence between local and remote is automatically handles.
RESTDroid is alpha released. You can have a look to RoboSpice. It's a powerful library to manage REST call but it's up to you to manage the persistency between local and remote resources.
1) The WCF-SOAP world is simple. You can pass any complex arguments you want and return any complex results you want. Logically, it’s just a Remote Procedure Call.
- IN REST:"You can pass any complex arguments you want and return any complex results you want too.
2a) Forgeting about the religion, what’s wrong with using a GET for everything?
In SOAP services WCF/or classical you are wrapping all requests into http POST so using single verb would end up to SOAP or - don't even think about it - your own communication protocol:-D
2b) You can technically compose GET request with non empty body - most of the servers ignore it by default though and it would be technically problematic to read it..
the other part of the question is answered by Pcriulan above
I'm looking for some best practice concepts as far as transferring data between a mobile device (Android right now, but concepts apply pretty much to the rest as well). I currently have a WCF service set up with a working JSON endpoint. I'm starting to modify the existing service methods with the appropriate WebGet/Invokes, etc to make it RESTful. The service implements the request/response pattern so that all communication between a client and the service are wrapped in a complex MessageRequest and MessageResponse object.
What is the best way to have a mobile application successfully utilize this pattern? There are only two solutions I can come up with, each with their own pros and cons:
Create all the data transfer objects in the client project, and then create a JSON/DTO mapper (GSON might work well here). Use the client-side objects to handle all client data management until a server request is necessary, go DTO-to-JSON, and send the request to the server. The upside here strikes me is that it makes client-side data management easier because it parallels the service domain. The downside is that these have this has the potential to breakdown the more complex an object becomes.
Ignore the DTOs client side and just do everything straight from the JSON. The upside here is that it removes the overhead associated with the larger objects and the required mapping. The downside here is that this strikes me as being very brittle - any changes to the returning object need to be handled deep in the code, rather than just making the change to the client side DTO and mapper.
Is there a better way to accomplish this data exchange? Or are these the only real ways to handle it? How do you manage data transfer in your mobile applications?
I have a very similar WCF setup as you do, and I ended up creating very lightweight data objects client side. These manage pulling apart a JSONObject representing themselves and create any sub-objects they need, but aside from that are simple classes mostly used to group data together and contain no business logic. We haven't yet needed to do any client side caching, but these objects would be a great place to put in SQLite code to persist themselves out.
It has worked great so far, and we were even able to port the client-side Android code to another project running regular Java just by including org.json.