They tell everywhere that we should use ASyncTaskLoaders because they are very good at not blocking the UI thread. And there is Volley to use now.
I guess we cannot use both of them because Volley does backgrounding on its own. What do you think? Which one is better?
These 2 technologies are different and hardly comparable. They have different purposes and can also work together. You could for exemple implement a Loader that uses Volley to load the data and inherits directly from Loader (not AsyncTaskLoader, because Volley handles the threading as well).
Main advantages of using Loaders:
Lifecycle is synchronized with the Activity/Fragment lifecycle automatically
Data and loading state is not lost on configuration change
The loader monitors changes and pushes new results automatically to the client fragment/activity.
Main advantages of using Volley:
High performance network stack
Automatic disk cache that respects the HTTP server policy
Powerful cancelation mechanism.
You can combine both to get both sets of advantages or you can use Volley without loaders with its simple API.
I've been using Volley for a month now and I have to say that I'm very satisfied. It really does help a lot not to have to worry about threading implementation details. So far both general networking and remote image loading have been working great.
It's not that there are no issues, but so far they have been minimal.
You better ask like this volley vs Async vs RxJava
You can use this RXJava for background thread, but for better efficiency in calling restful services Volley is highly recommended, also very less coding required compare to async task loaders !
Here is a writeup on current Android best practices. It discusses the use of Volley and RXJava: https://github.com/futurice/android-best-practices
You can combine both, to get both advantages.
In your activity (main thread) you call your API with Volley.
With a simple interface mechanism, you callback your main thread when the data is available.
Then you forceLoad() your AsyncTaskLoader with the fresh data from Volley.
In your AsyncTaskLoader you hydrate all your activity's container. They will be automatically loaded when data is available.
With this approch you combine Automatic disk cache of Volley, and Automatic synchronization of Loader.
Related
I want to refactor my app using Volley as HTTP library.
The current architecture includes using IntentService and AsyncTaskLoader for handling REST requests, and both of them start a new background thread.
Is it possibile to keep the current architecture and use Volley in conjunction with IntentService and AsyncTaskLoader?
I presume that to do this I should use Volley starting synchronous requests inside IntentService or AsyncTaskLoader, but looking at documentation and examples this doesn't look like the standard way to use Volley and maybe it would also decrease the performance benefits of the library itself.
Does introducing Volley mean getting rid of Services in our Android apps architecture?
I am using the Retrofit 2 library for an android REST client. Retrofit itself supports synchronous and asynchronous request (cf. here), the reason for the latter being not to block a thread and thus not to get interrupted by android.
In practice, is it better to use synchronous calls in a native AsyncTask or asynchronous calls directly from Retrofit?
If one is preferable over the other, what are the technical reasons?
One of the main reasons to use any of the popular REST clients (retrofit, volley, etc) is that they reduce the amount of details you have manage at the application layer. One of those details is making sure your network requests happen off the main thread. Why would one use an AsyncTask when a library they are already using for other features provides the same functionality with less ceremony? The only reason I can think of is -- you don't think the library's threading is very good. That concern does not apply to retrofit 2, it uses OkHttp to dispatch async calls. OkHttp has been around awhile and used extensively, it manages its own thread pool to execute async requests, and is solid.
So, the upside to using retrofit async is cleaner code, and no downside I know of vs AsyncTask with retrofit sync calls. The only time I use the sync calls is when my code is already executing in a background thread for another reason. I never create a separate thread or asynctask just for the network call and use enqueue instead.
I kinda liked Volley framework, but I still have some doubts about it.
For example, how does Volley line up with Loader pattern? Since it's requests are handled in an async manner, calling it on background doesn't make much sense. On the other hand, if we ignore the Loader pattern, we will cancel the loading and reload the necessary resources, it's kinda waste.
How does Volley framework work with Loaders in Android?
A Loader can encapsulate practically anything, including Volley requests. When your Loader encapsulates a framework that already handles background work for you and calls you back on the main thread, like Volley, your loader implementation must not inherit from AsyncTaskLoader but simply from the Loader base class. You would then start the Volley request in the onForceLoad() method.
When your loader gets the result back on the main thread through a callback, it just needs to push it to the Activity/Fragment by calling deliverResult().
Your loader would also need to keep a reference to the Volley request in progress to be able to cancel it in onStopLoading(). onStopLoading() is not called in case of configuration change like screen rotation, only when leaving the Activity.
The only disadvantage is that Loaders don't have a built-in mechanism to propagate errors, while Volley does. So in your Volley error callback inside of your Loader, you'll need to either deliver a null result or send a local broadcast to notify the Activity/Fragment of the error.
AFAIK and I have seen in the sources, responses to your requests will be cached, IF the server sends the proper caching headers(ETag), and the second time you will attempt to make a GET request, to the same url, you will be provided with a response from the cache, instead of calling the Network again.(by default Volley caches the requests using as key the URL).
Adding Requests to the RequestQueue should be done from the MainThread, as it makes no sense to call them from a background Thread.
I just publish an article about Volley and it integration into project over Loader pattern. Advanced approach is shown. Loader states are fully defined and displayed in diagram.
Article: https://plus.google.com/117981280628062796190/posts/8b9RmQvxudb
It is possible to make synchronous requests with Volley via the RequestFuture class. I haven't looked into this personally, but it looks like you could leverage that with a Loader to get the best of both worlds (Volley's Cache with the loading stability of the Loader).
For what I understand, the Loader framework is geared towards accessing data stored locally in a ContentProvider / SQLite database. We have the CursorLoader class that handles this use case quite well.
But I wonder if it's practical to use the Loader framework to write classes extending Loader / AsyncTaskLoader to access remote web services (e.g. a REST web service)? I always thought that this framework is a bit too rigid and confusing (lack of proper documentation) for this use case. I prefer handling REST calls in more regular way, using AsyncTasks / Services. But recently I've found some articles that used AsyncTaskLoaders and began to wonder.
So why would anyone use Loaders to access Web Services? The only advantage I see here is that Loaders retain their results automatically. There's no Cursor here to manage afterwards.
Realistically, you probably want to use a networking library like Volley. This has some nice features like request batching and image caching. Nonetheless, for the sake of argument lets compare Service, Loaders and AsyncTask.
Services are the way to go if you want to allow the loading to continue while changing Activities or backgrounding your application. Or, if you want to export your service so multiple applications can use it. Otherwise, use a Loader or AsyncTaskLoader.
Loaders have a few advantages over AsyncTasks.
They are less likely to cause crashes by executing code after the Activity has finished, since they are aware of the android lifecycle.
The design discourages having references to Views or Activities. This reduces the likelihood of forcing the Activity to stay in memory after it has already finished.
Monitor the data source for changes and trigger callbacks when they occur
They have built in caching that can be useful after rotations. For Cursors, the CursorLoader automatically reconnects at the correct position to the last Cursor loaded
However, they also have disadvantages
The API is extremely more cumbersome than AsyncTask. Especially if you care about compatibility with older versions of Android
You are already storing UI state inside onSaveInstanceState(), so using the Loader's causes you to save state in multiple ways. This can be confusing to read and understand. Especially if you end up mixing retained fragments into the mix.
The Loader caches the loaded result, not the UI state that you actually need
I'm assuming you are just reading from web services, not writing. If you are performing updates to a web service and you need to see the service's response, then this changes things. Using an AsyncTask could prevent you from getting the response if the it is received during a rotation.
There are cases where Loader is suitable for webservices: When your server can send push notifications back to client to notify that data is changed.
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:
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).
I also have to cancel them all (or handle in a different way) when the activity/fragment is being re-created.
Because of 1&2, I need to manage them and have a reference to all of them
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?
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.
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
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.