42

I've seen any number of examples and they all seem to solve this problem differently. Basically I just want the simplest way to make the request that won't lock the main thread and is cancelable.

It also doesn't help that we have (at least) 2 HTTP libraries to choose from, java.net.* (such as HttpURLConnection) and org.apache.http.*.

Is there any consensus on what the best practice is?

Jeremy Logan
  • 47,151
  • 38
  • 123
  • 143
  • Has anyone used [this](http://loopj.com/android-async-http/) library before? It looks good, but im not sure how it handles failed requests (or even if it works!) – Robert Jun 27 '11 at 10:21
  • Would you share your HttpTask class? – the_machinist_ May 29 '12 at 01:35
  • Check out the following link for a simpler approach: http://masl.cis.gvsu.edu/2010/04/05/android-code-sample-asynchronous-http-connections/ – ANUP Sep 16 '11 at 06:00
  • not simpler at all. Also the best practice is to use AsyncTask for asynchronous operations (HTTP requests or else). – jeremy Jul 18 '12 at 09:04

4 Answers4

35

The Android 1.5 SDK introduced a new class, AsyncTask designed to make running tasks on a background thread and communicating a result to the UI thread a little simpler. An example given in the Android Developers Blog gives the basic idea on how to use it:

public void onClick(View v) {
   new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask {
   protected Bitmap doInBackground(String... urls) {
      return loadImageFromNetwork(urls[0]);
   }

   protected void onPostExecute(Bitmap result) {
      mImageView.setImageBitmap(result);
   }
}

The doInBackgroundThread method is called on a separate thread (managed by a thread pooled ExecutorService) and the result is communicated to the onPostExecute method which is run on the UI thread. You can call cancel(boolean mayInterruptIfRunning) on your AsyncTask subclass to cancel a running task.

As for using the java.net or org.apache.http libraries for network access, it's up to you. I've found the java.net libraries to be quiet pleasant to use when simply trying to issue a GET and read the result. The org.apache.http libraries will allow you to do almost anything you want with HTTP, but they can be a little more difficult to use and I found them not to perform as well (on Android) for simple GET requests.

jargonjustin
  • 2,199
  • 1
  • 19
  • 8
  • Thanks. I had actually found the AsyncTask(in 1.5) and UserTask(for 1.1) and have written a generic HttpTask. Pretty much the only thing I have left to do is figure out how to handle a screen rotation while a request is active. – Jeremy Logan May 13 '09 at 02:03
  • 4
    For new users reading this answer: *beware*. It's a quick and dirty fix for a complex problem. As Snicolas points out in his answer, it's flawed and buggy. It is also not consistent on how it will handle multiple concurrent tasks (http://developer.android.com/reference/android/os/AsyncTask.html). From Honeycomb, all tasks will execute on a single thread - meaning that you will not achieve multiple HTTP calls in parallel unless you specifically ask for `THREAD_POOL_EXECUTOR` and implement the concurrency plumbing needed for that. – Nilzor Apr 04 '13 at 09:04
12

Actually there are a couple of flaws in the design of AsyncTasks that prevent it from being really usable for networking. An easy example is that you will loose the link between your AsyncTask and your Activity ... just by rotating your device.

Have a look at this thread : you will see that AsyncTask also very easily create memory leaks.

The AsyncTask documentation is clear about that : AsyncTask should only be used for short living tasks and, obvisouly enough, networking doesn't belong to that category.

So, I really suggest you have a look at RoboSpice. This library has been designed for asynchronous networking and it's a very robust way to implement it. If you only have a few seconds to be convinced, look at this inforgraphics.

RoboSpice also as a demo application on the store : RoboSpice Motivations that will explain everything, in depth, about asynchronous networking on Android.

Community
  • 1
  • 1
Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • 1
    I believe you are wrong as to what Google intends AsyncTask to be used for. They define "short living tasks" as "a few seconds at the most" (http://developer.android.com/reference/android/os/AsyncTask.html) and indeed gives a code example where a file download from a URI is executed. – Nilzor Apr 04 '13 at 08:24
  • Did you try rotating your device while downloading ? Indeed, there are a couple of issues, but also a couple of workarounds. The problem is that they tend to be very very complex to implement properly and code is not reusable. As an example, I suggest you have a look at RoboSpice motivations on the store. – Snicolas Apr 04 '13 at 08:26
  • 1
    (Being pedantic:) I still believe you are wrong as to what **Google** preaches. Which is scary - because **I** also believe AsyncTask is not a good fit for HTTP requests. Even more so now, after having tested rotating my device and the motivations app as you suggested. *edit*: It was your sentence "The AsyncTask documentation is clear about that" which triggered my comment because I disagree. – Nilzor Apr 04 '13 at 08:47
  • BTW have you checked out Android Asynchronous Http Client (http://loopj.com/android-async-http/) and can you say anything about how that compares to Robospice? – Nilzor Apr 04 '13 at 08:54
  • 2
    Nope, but a comparison would be welcome. BTW, the comments begin to be hard to read. If we agree on the fact that AsyncTasks are a bad fit for networking, we should just say that. – Snicolas Apr 04 '13 at 19:06
1

What about an AsyncTask with a reference to a static retained Fragment (without an UI) hosted in an Activity or another fragment ? No memory leaks, elegant async operations in a separate thread, no object reference losses.

I think this would be ok for http request, but not for file uploads / downloads. If you read carefuly, there is a sentence:

If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.

But they do not mention, that a service with a separate Thread could be a good option too. This is meant to continue executing the tasks in background, no matter what the user does. (d.g. if he uploads some file you do not want to stop this because he has left the activity)

This link for samples - find the RetainedFragment.java

This link for AsyncTask.

theSpyCry
  • 12,073
  • 28
  • 96
  • 152
  • This question is so horrifically out of date I hope no one considers it relevant to the modern state of affairs. There have been may libraries that have solved this problem in the intervening years. – Jeremy Logan Dec 20 '13 at 06:47
-1

You can use Async Task for Android. To make http request you can use HttpURLConnection class.

Ashish Vora
  • 571
  • 1
  • 8
  • 27