I'm using Retrofit for making HTTP calls. But it seems like the library is compressing (gzip) the request by default. Since the API can't handle compressed request, is there any way to turn-off default compression?
Retrofit does no compression. In fact, it's barely involved in HTTP at all as it just delegates the hard work to a real HTTP client.
That said, I'm going to guess you're talking about OkHttp, but OkHttp also does no compression by default. Adding request body compression is one of the examples we provide. Since it's not supported by a large majority of webservers by default, it isn't enabled by default.
OkHttp will automatically add an Accept-Encoding: gzip header to requests. This indicates to the server that OkHttp can read Gzip response bodies. If the server chooses to send a Gzipped response body (it doesn't have to), it will be transparently un-Gzipped before being handed back to the application code.
I am trying to use the built in HTTPResponseCache in my app (making requests via the HTTPURLConnection API) but am having problems trying to get it to cache any responses that were requested with an Authorization header included.
The only way I can get it to cache the response at all is to explicitly put 'public' in the Cache-Control response header on the server (s-maxage might work too, haven't tried, but explicitly putting private results in no caching); but this will mean that any intermediate proxies will cache the response to serve to other clients, which is not what I want.
My understanding is that a user agent cache would cache responses requested with Authorization headers by default or with a private header. It seems like the HTTPResponseCache is acting like a shared cache in how it is interpreting the headers, rather than a user agent cache. Or is my understanding of the caching standards not correct?
Is there any way I can get the cache to act like a user agent HTTP cache?
This in my install code:
public static void setupCache(Context context, long httpCacheSize){
File httpCacheDir = new File(context.getCacheDir(),"http");
HttpResponseCache.install(httpCacheDir, httpCacheSize);
}
Do I need to do something different here? Or perhaps I need to include some user agent information in my requests?
Whilst I found no solution to this specific issue, I worked around my problem by refactoring my HTTP client code to use Volley (http://developer.android.com/training/volley/index.html) rather than HTTPURLConnection. The caching facilities in Volley are implemented separately to HTTPResponseCache and implement handling of cache control headers as expected for a user agent cache.
Wanted to know what would be the most efficient way of doing this. The reason I want to divide the file is so that I dont send the same blocks of data again if the network becomes unavailable while the transfer is going on. This is especially usefule for bigger files.
What you want is an HTTP Multipart Request, which is provided by the Apache HTTP Library, by Retrofit and by Ion. Volley does not let you perform such a request currently.
I have an issue using Volley with conditional GETs on cached responses when the request goes through one or more redirect hops.
On the initial request, if the server responds with a 302, the HTTP stack (I'm using the default HurlStack) transparently follows the redirect(s) and ultimately returns the response from the final server.
On subsequent requests, Volley adds an If-Modified-Since header to perform a conditional GET, but these are sent to the initial server, so instead of redirecting we just get a 304 response and the request never reaches the final server.
Since Volley is very loosely coupled with its underlying HTTP stack, there's no way to communicate the fact that the cache headers should only be sent with the final request.
The best solution that I can see (besides never sending conditional GETs) is to write a custom HttpUrlConnection implementation that recognizes that certain headers belong to a specific URL and only sends those headers when appropriate. This means, I would have to save the URL of the final server somewhere, probably as a custom header so that it is saved in the cache along with the other headers.
A slightly less hacky solution would be to write a custom HttpStack implementation that handles redirects manually. But that would mean we could not reuse the connection for redirects to the same host, so it would be less efficient.
Has anyone else run into this issue and have a better solution? It doesn't seem to be specific to Volley or HttpUrlConnection, but to any HTTP library that handles redirects transparently. How do you tell it which headers go with a given URL?
I am just learning about Android Development so excuse me if this is a bit off in nature.
I am wanting to make an app that interacts with a Database from my website, in a sense the two things will be one feeding the other. So with that. I am trying to figure out whats the best way to interact with my server. I don't want an app thats an app in a browser like environment I want to dev a full app that works independently of the site only sharing the DB and like features. So what would be my best approach?
Is building the app so it can post/get to php files on the server interacting basically through JSON/XML my best and or safest bet or is there a better approach that connects the App to the servers Database that doesn't require me to open the database to any ip that makes a request.
Just looking for opinions and suggestions here. I figure everyone who's going to see this is familiar with Android development and best practices where as I could and have surfed blogs and all else but the opinion seems to be 50/50 as to which is best.
I'm sure there are libraries out there for Android that help you with HTTP Get and Post, however, if you really want to understand what is going there are just a couple of classes you have to understand in order to make the necessary classes yourself.
First, get to know HttpClient, HTTPGet, HTTPPost, and HTTPResponse. Some of the later versions of Android have some nice other classes as well, but those four is pretty much all you need to get started.
You need to do something like this:
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.myurl.com/api_name");
HttpResponse response = client.execute(request);
If you debug this (with a real URL of course), you'll notice that your app kind of freezes during client.execute(). This is the point at which the request has actually fired and the app is waiting for a response. Once you actually get the response, it isn't very difficult to get the data out of it.
Once you understand this, you'll want to get to know AsyncTask, which is endlessly useful for performing background tasks. You can find the documentation here: http://developer.android.com/reference/android/os/AsyncTask.html There is a great example of how to use this right at the top.
Using these two concepts together you can perform asynchronous HTTP requests. Basically, put your actual HTTP execute code in doInBackground of your AsyncTask. At the end of the doInBackground return your response, and then do what you want with your data in the AsyncTask's onPostExecute.
We've found that providing a proper RESTful web API that hits the database on the backend in whatever language you choose (be it PHP, RoR, whatever) provides a useful interface for any number of uses (your own website, mobile apps, etc).
Then it's a matter of your Android app interacting with the RESTful API, which is simply HTTP requests. Those can be encapsulated in helper classes to make them straightforward as well.
Based on my experience, the best framework for doing RESTFul things with Android is: Spring Android
From a client perspective, it provides all the tools needed to access secure RESTFul services. Since it is Spring, it provides nice abstractions over most of the boiler plate http code. As an example, it provides a clean way to perform a GET that returns json, and then serialize that to a POJO.
As an example:
RestTemplate restTemplate = new RestTemplate();
// Add Jackson JSON Message Converter to Template
restTemplate.setMessageConverters(
new ArrayList<HttpMessageConverter<?>>() {
{
add(new MappingJacksonHttpMessageConverter());
}
}
);
// Simple Conversion - pojo is now populated
MyPojo pojo = restTemplate.getForObject(url, MyPojo.class);
The approach you mention in the question: PHP on the server and JSON for requests/responses, does work. But getting it perfect can be tricky.
I found it helpful to have small request/reponse classes for each call on the Android side, like SaveNoteToServerRequest, SaveNoteToServerResponse classes which are just plain java objects with whatever fields are needed for the request/response. Then you can use a library like GSON to convert the request object to JSON and convert the http response from JSON to the response object.
On the PHP side you can create a small class for the response object, then json_encode at the end.
That way you're not directly manipulating JSON objects, just using your own plain java objects or php classes most of the time.
Hope that helps.