Is there an accepted best-practice on making async

2019-01-16 09:49发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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