Is using AsyncTask still recommended for loading l

2019-03-20 11:57发布

问题:

Background

I've heard that there are some new solutions for loading data in the background which are more recommended than AsyncTask (like loaders).

The problem

AsyncTasks are great and easy to use. However, it has some limitations:

  1. The class itself has to be modified since it's limited by the number of pending tasks (about 256 or so). Of course, in a listView's adapter, I always cancel a task if it's not needed(for example when I need to update a view that was used for a different item).

  2. I also have to cancel them all (or handle in a different way) when the activity/fragment is being re-created.

  3. Because of 1&2, I need to manage them and have a reference to all of them

  4. AsyncTask uses a queue of tasks, and sometimes I need to use a stack instead, so I had to create my own class of AsyncTask that uses a stack instead.

The question

Are there alternatives for AsyncTask?

I know this was asked in some posts before (like here), but I was thinking if there is a new general way to load data in the background which replaces the asyncTask.

About Loaders, I think the idea is that they are used for databases and contentProviders, but can they also be used for loading (for example) data from the Internet (like images files) ?

There is also a nice sample made by google (here, called "bitmapFun"), which according to what I see uses AsyncTask (and even extend it, maybe because of the same reasons I've mentionsed) . But maybe I'm missing there something too?

回答1:

Maybe you should consider reviewing your approach, the need you have for performing several updates depending on the view and cancel all the pending tasks from the previous views gives the impression that you are performing the load of data individually for every view that needs to be created.

In a list view with a list adapter, the usual approach is to load a portion of the data (either as list of ValueObject or as Cursor from multiple database rows) paginated on demand or in one goal, not item by item. So if you wish to update the next page, you basically perform one single operation, either using AsyncTask or Loaders to fetch the new items to the model then making it available for the UI to display them. This way, you will be applying MVC, and you won't have several pending tasks to cancel and control, and your structure would be more solid and easier to manage.

About the alternatives, If you're dealing with database, the most straightforward way is to use the CursorLoader, i.e. the loaders instead of AsyncTask, but if you're dealing with data that comes from the network or filesystem, you're kinda free to choose from the variety of other options available. AsyncTask is much more simpler to use, mostly recommended for simple things or one shot queries. But you can also use Loaders for such tasks as well, see AsyncTaskLoader.



回答2:

Yes.

Loaders are managed AsyncTasks. If you are not using a Loader, you are probably missing the management that they require.

AsyncTasks (and Loaders) are a pretty bad way to get stuff that is off the device. To get data from a remote server look into using an IntentService. See: https://www.youtube.com/watch?v=xHXn3Kg2IQE



回答3:

AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) 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. See the http://developer.android.com/reference/android/os/AsyncTask.html for more info.

An alternative to asynctask is robospice.https://github.com/octo-online/robospice.

You can get started with robopice here. https://github.com/octo-online/robospice/wiki/Starter-Guide.

A sample of robospice at https://play.google.com/store/apps/details?id=com.octo.android.robospice.motivations&feature=search_result.

Some of the features of robospice.

1.executes asynchronously (in a background AndroidService) network requests (ex: REST requests using Spring Android).

2.is strongly typed ! You make your requests using POJOs and you get POJOs as request results.

3.enforce no constraints neither on POJOs used for requests nor on Activity classes you use in your projects.

4.caches results (in Json with both Jackson and Gson, or Xml, or flat text files, or binary files, even using ORM Lite).

5.notifies your activities (or any other context) of the result of the network request if and only if they are still alive

6.no memory leak at all, like Android Loaders, unlike Android AsyncTasks notifies your activities on their UI Thread.

7.uses a simple but robust exception handling model.