📜 ⬆️ ⬇️

What kind of library to work with HTTP in Android choose?

I present to you the translation of the article “ Which Android HTTP library to use? ".

What is it for?


Today, almost all applications use HTTP / HTTPS requests as a transport for their data. Even if you do not directly use these protocols, many SDKs that you most likely have already included in your applications (for example, metrics, crash statistics, ads) use HTTP / HTTPS to work with the network. To date, very few libraries exist that a developer could freely use in his project. And I will try to tell about the main ones in this post.
Android developers have many reasons to opt for third-party libraries, instead of already built-in APIs, such as HttpURLConnection or Apache Client. For example:

  1. Ability to cancel a network call
  2. Parallel query execution
  3. Connection pooling and reusing existing socket connections
  4. Local server response caching
  5. Simple asynchronous operation interface to avoid blocking the main or UI threads
  6. Convenient REST API wrapper
  7. Retry and Delay Policy
  8. Efficient loading and transformation of images
  9. JSON serialization
  10. Support SPDY, http / 2

A bit of history


At the very beginning, there were only 2 HTTP clients on Android: the HttpURLConnection and the Apache HTTP Client. According to an official Google blog post, HttpURLConnection had several bugs in earlier versions of Android:
Before Froyo, HttpURLConnection had some not very nice bugs. In particular, the close () call to the readable InputStream could spoil the connection pool.

At the same time, Google did not want to develop and switch to the Apache HTTP Client:
... the large size of their API prevents us from improving this library without losing backward compatibility. The Android team is not actively working on the Apache HTTP Client.

Before Froyo, most developers preferred to use different clients based on the OS version:
The Apache HTTP client has few bugs on Eclair and Froyo, so it is the best choice for these versions. And for Gingerbread and younger HttpURLConnection is better suited. The simplicity of the API and low weight are well suited for Android. Transparent compression and response caching help increase speed and save battery. New applications should use HttpURLConnection.

Even today, if you take a look at the Volley source from Google (I'll talk about it a little later), you can find this legacy:

if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { stack = new HurlStack(); } else { // Prior to Gingerbread, HttpUrlConnection was unreliable. // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } } 

This is a classic example of the fragmentation of Android, which makes developers suffer. In 2013, Square drew attention to this problem when it released OkHttp. OkHttp was created to work directly with the top level of Java sockets, without using any additional dependencies. It comes in the form of a JAR file, so developers can use it on any JVM device (where we include, of course, Android). To simplify the transition to their library, Square implemented OkHttp using the interfaces HttpUrlConnection and the Apache client.
')


OkHttp has received a lot of distribution and community support, and in the end, Google decided to use version 1.5 on Android 4.4 (KitKat). In July 2015, Google officially recognized the Apache-based AndroidHttpClient as obsolete, along with the release of Android 5.1 (Lolipop).

Today, OkHttp comes with the following huge feature set:

  1. HTTP / 2 and SPDY support allows all requests going to the same host to share a socket
  2. Merging requests reduces latency (if SPDY is not available)
  3. Transparent GZIP allows you to reduce the weight of downloadable information
  4. Caching responses allows you to avoid working with the network with repeated requests.
  5. Support for both synchronized blocking calls and asynchronous calls with a callback

My favorite part of OkHttp is how beautiful and neat you can work with asynchronous requests:

 private final OkHttpClient client = new OkHttpClient(); public void run() throws Exception { Request request = new Request.Builder() .url("http://publicobject.com/helloworld.txt") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, Throwable throwable) { throwable.printStackTrace(); } @Override public void onResponse(Response response) throws IOException { if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string()); } }); } 

This is very convenient, since working with the network should not be in the UI stream. In fact, starting with Android 3.0 (Honeycomb, API 11), working with the network in a separate thread has become mandatory. In order to implement something similar with HtttpUrlConnection, you will need to build a large (and maybe even monstrous) construct using AsyncTask or a separate stream. This will be even more difficult if you want to add cancellation of the load, merge of connections, etc.

By the way, Google’s Google’s Volley’s HTTP library, which provides us with the following bonuses:

  1. Automatic scheduling network requests
  2. Many parallel network connections
  3. Transparent caching in memory and on disk, in accordance with standard cache consistency.
  4. Support prioritization queries.
  5. Cancel API requests. You can cancel both one request and the whole block.
  6. Easy to set up, for example, for repetitions and delays.
  7. Strict ordering that makes it easy to populate the user interface data asynchronously from the network.
  8. Debugging and tracing tools



Everything Volley has is at the top of the HttpUrlConnection. If you want to get JSON or an image, then Volley has a special abstraction for it, such as ImageRequest and JsonObjectRequest, which help you automatically convert the HTTP payload. It is also noteworthy that Volley uses a hard-coded network pool size:

 private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4; 

When OkHttp uses a thread for each call with a ThreadPoolExecutor with a maximum value of Integer.MAX_VALUE:

 private int maxRequests = 64; private int maxRequestsPerHost = 5; executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false)); 

As a result, in most cases OkHttp will act faster due to the use of a large number of threads. If for some reason you want to use OkHttp together with Volley, that is, the implementation of HttpStack , which uses the API of requests / responses from OkHttp instead of HttpURLConnection.

HTTP clients continued to evolve to support applications with a large number of images, especially those who support endless scrolling and image transformation. At the same time, the REST API became the standard in the industry, and each developer dealt with such typical tasks as serialization to / from JSON and conversion of REST calls to Java interfaces. Not a lot of time passed, as libraries appeared that solve these problems:

  1. Retrofit is a type-safe HTTP Android client for interacting with REST interfaces.
  2. Picasso - a powerful library for downloading and caching images for Android

Retrofit provides a bridge between Java code and the REST interface. It allows you to quickly include APIs in your HTTP project, and generates a self-documenting implementation.

 public interface GitHubService { @GET("/users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user); } Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") .build(); GitHubService service = retrofit.create(GitHubService.class); 

In addition to all, Retrofit supports converting to JSON, XML, protocol buffers (protocol buffers).

Picasso, on the other hand, provides an HTTP image-oriented library. For example, you can load an image into your View with one line:

 Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView); 

Picasso and Retrofi are configured to use OkHttpClient as a standard HTTP client. However, if you prefer, you can specify an HttpURLConnection client.

Glide is something like Picasso. It provides some additional features, such as GIF animation, generating thumbnail image thumbnails and still videos. Full comparison can be found here .

Facebook recently opened to the public the source code of the Fresco library, which they use in their mobile app. One of the key functions that allocates it is the custom memory allocation strategy for bitmap to avoid the work of a long GC (garbage collector). Fresco allocates memory in a region called ashmem. Some tricks are used to have access to this region of memory access from both the part written in C ++ and the part in Java. To reduce the consumption of CPU and data from the network, this library uses 3 cache levels: 2 in RAM, the third in internal storage.



I found it necessary to show the relationship between libraries on the same scheme. As you can see, HTTP always stays down in high-level libraries. You can choose between a simple HttpUrlConnection or the latest OkHttpClient. We use this compatibility when developing the PacketZoom Android SDK, which we will discuss in the next post.



We recently compared HTTP performance libraries to each other , but this topic deserved separate consideration. We hope that this review has given you basic ideas about the pros and cons of each library, and we helped you make the right choice. Follow the release of more interesting posts about networking in Android from us.

Source: https://habr.com/ru/post/281965/


All Articles