The android training said:
Volley is not suitable for large download or streaming operations, since Volley holds all responses in memory during parsing. For large download operations, consider using an alternative like DownloadManager.
I just wonder what is the threshold for use Volley or DownloadManager?
How to judge a download is a large download?
What is the typical case for use Volley and DownloadManager?
Well it's a decision solely depending on your user case, imagine you've an API which returns the profile of a user from your DB, formats it and creates a PDF for you. While you can use Volley for this too, but it's better done with a SystemService like DownloadManager which does the download operation completely in background and gives you a callback with the file downloaded.
While there isn't a threshold value as such, but consider it this way, if you wish to Download something, use the DownloadManager. There are use cases where a DownloadManager can not be efficient too, imagine you're requesting a JSON from the server and use a DownloadManager instead of a Volley request, the paritcular json is fetched completely in background and sent back to you, while this could much efficiently done with volley which gives support for handling different states inside the onErrorResponse and onResponse method.
Thus summarising, all the requests which you feel could affect the UI at the present instant and is not more than the average heap memory an application gets during it's runtime (approx. 20-40MB), and needs an instantaneous callback should be done using Volley. Else for operation which don't affect the present UI much and could be a complete background operation (even if the file size is just 500KB) with not need for an instantaneous callback should be done using DownloadMaanger
Hope this helps.
Related
I have the requirement of downloading several images and videos and the requirement entails "one time" download so there isn't really any caching required and that's why I am not using Volley. Volley for videos could be expensive.
Next, I stumbled upon built-in Android's DownloadManager which seems to facilitate downloads on a queue, the API doesn't seem bad overall but I was wondering how it might compare to using a Service with a ScheduledThreadPoolExecutor(an option dictated by one of the Commonsware's post)?
Note: My use case is strictly not that of downloading images for a grid with chances of repeated requests. My requests have to be single time downloads only. The request may be a mix of few images and videos.
Could the ScheduledThreadPoolExecutor inside Service be significantly faster?
I was wondering how [DownloadManager] might compare to using a Service with a ScheduledThreadPoolExecutor
DownloadManager does not require your process to be running, and it handles all of the issues with retry policies and so forth. On the other hand, DownloadManager:
Requires that the download be initiated from a simple URL (i.e., no session cookies)
Shows the user the results via the Downloads app
Can only easily download to external storage
Downloads one item at a time
May delay the download start for a while (e.g., if something else is being downloaded)
ScheduledThreadPoolExecutor is unlikely to be part of an in-process solution, though a ThreadPoolExecutor might. That would only be necessary if you needed to try downloading N videos at a time and you didn't want to use any multi-threading option offered by your HTTP client API (e.g., OkHttp). Since you want to download these things in the background (presumably), and you do not know what the user is doing in the foreground, I recommend only downloading one video at a time, so you do not make it difficult for the user to use the Internet from whatever is going on in the foreground.
Could the ScheduledThreadPoolExecutor inside Service be significantly faster?
You are comparing apples and asteroids.
Neither ScheduledThreadPoolExecutor nor Service perform HTTP downloads. An in-process HTTP client API (HttpUrlConnection, OkHttp, Volley, etc.) performs HTTP downloads, as do some out-of-process options (notably DownloadManager).
A proper comparison would be between DownloadManager and the combination of:
An in-process HTTP client API, and
Some form of service, to allow the download to go on even if the user navigates away from your UI
From a pure speed standpoint, any HTTP client API will be limited by the network and so should perform roughly equivalently. Volley is not well-suited for large downloads because it puts the entire result in memory, and you don't have heap space for a video. Other options will let you stream the results to a file.
I'm new to Android Development, and I've run into this problem that I haven't found a solution for.
It starts off first with going to a webservice api for login. From there if the login is successful it executes to 2 functions for the actually data it needs, stores in sqlite and then proceeds to next activity. All 3 api requests are using AsyncTask and from what I understand my Activity is actually running faster than my "doInBackground" background thread. I want to know the path or what i should look into. I've read posts about using sleep, and read posts about how that is bad to do. I want to get the json data i need, store it, and use it immediately. I think i'm suppose to find away to connect directly and use a progress bar to get the data. Keep in mind, it's not a lot of data, but it's enough to stall my application.
Not sure what a ProgressBar has to do with retrieving data from a server but if you're looking for AsyncTask alternatives (particularly for HTTP calls) you can look at these frameworks (you'll probably only want to pick one):
Square's Retrofit
Google's Volley
Either one will make your life a lot easier when it comes to making HTTP requests. Their own documentation explains how to use them pretty well so I'm not going to go into how to use it here.
If you're looking for a native, lower level AsyncTask alternative, have a look at AsyncTaskLoaders. The AsyncTaskLoader essentially does exactly the same thing as an AsyncTask but they live within the life cycle of the Activity or Fragment so your code tends to be less error prone.
Hi i am working on an android application. Its a you tube type of application.
I am facing one issue . There is a download feature in my app. When i start downloading some content then during downloading if i will create any another network connection then it will take more time.
For Downloading i used a Asyntask handled by a services.
and for simple network call i used a Asyntask.
Then kindly please suggest me how can i overcome with this problem.
My expectation is if downloading is in progress then if i make some network call then this network call should be on high priority.
Please suggest.
If you are using asynctask, you can attempt setting the priority of the current thread using something like this.
protected void doInBackground() {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
// download the things
}
Asynctasks are usually lower priority. You can read more about it here:
http://www.androiddesignpatterns.com/2014/01/thread-scheduling-in-android.html
If you are using many HTTP requests, I do however recommend you use a library, like Volley. This allows you to easily set up a request queue, and jump the queue for high priority items.
You can read more about that, here:
http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/
I have to send four different request in an api at the same time. Do i need to make AsyncTask background thread for each request or all request could be done through a single AsyncTask. Can somebody please help.
This is a concurrency issue. There is literally dozens of ways to do this in Android. I've written almost every single one for courses that cover this material... and even then it isn't 'simple'.
I'd personally make use of HaMeR (Handler, Messages, Runnable) framework of Android. Create 4 runnables and have them post their results to a Handler.
However... That isn't the easiest to implement. and would require you to understand how to safely create your own custom handler (making use of WeakReference properly, etc.)
Therefore, I'd recommend running the asyncTask(s) on the executorService
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); The default thread pool executor should start with 4 threads (I believe off-hand without looking it up).
I am assuming you are using HttpURLConnections. Unfortunately each of those connections, as specified in the documentation, is capable of handling only a single request.
However, you can (and possibly should) still perform all your requests in a single AsyncTask. Each AsyncTask will require the creation of a new thread which takes lots of time and resources. So don't listen to anyone who tells you to create a new task for each request.
You also have the option of exploiting HTTP persistence. If you add the header Connection: Keep-Alive to your request via connection.setRequestProperty("Connection", "Keep-Alive");, you will be able to send multiple requests over the same connection and save a lot of time and resources.
It's a little complicated in Java, because of the one-request-per-httpurlconnection rule, but it can be done. First, when you are done with your first request's HttpURLConnection do not close that connection. Then, to create the next connection, call url.openConnection() on the same URL object that you used to create your first HttpURLConnection. The JVM will know to reuse that connection if possible to save bandwidth.
You also have the option of using HTTP/2.0 multiplexing, which allows you to send multiple requests literally at the same time. Unfortunately I am not yet well versed enough in HTTP/2.0 to tell you exactly how to make use of this, but the multiplexing feature was included to solve exactly this problem.
According to EventBus doc, there are 4 types of thread modes which EventBus uses to deliver threads:
onEvent()
PostThread
Good for simple tasks
onEventMainThread()
MainThread
a.k.a. UI Thread
Good for UI changes
onEventBackgroundThread()
BackgroundTread
Using single thread, delivering events sequentially.
Good for execution requiring moderate amount of time.
onEventAsync()
Async
Using separate threads.
Good for execution requiring longer time
Question
What are some criteria I should examine before I use onEventBackgroundThread() over onEventAsync(), or vice versa? What would be some examples of using one over the other with obvious advantages?
Which thread modes should each of the following functions use?
Getting the device status -- GPS location of the device (i.e. android.location), Internet connectivity status (i.e. ConnectivityManager, NetworkInfo).
Making simple HTTP requests to receive text (e.g. JSON), taking anywhere between 1000ms to 5000ms, average 2000ms.
Making simple HTTP requests to load images with file sizes between 50kb to 1500kb (exact sizes are unknown to client, before making requests to server).
Caching data to internal database (e.g. SharedPreferences, SQLite, etc).
What are some criteria I should examine before I use onEventBackgroundThread() over onEventAsync(), or vice versa? What would be some examples of using one over the other with obvious advantages?
Well, it's pretty much as the bullets outline. If you don't mind queued, one-at-a-time processing (or perhaps you want it for simpler thread safety), use onEventBackgroundThread(). If you need to do several of them in parallel, particularly if they are I/O-bound, you'd use onEventAsync().
Which thread modes should each of the following functions use?
GPS location of the device (i.e. android.location)
None of the above. LocationManager and the fused location API have their own asynchronous options; I'd use those. Once you get the location handed to you, you could post an event with the location data, but then the threading is dictated by the subscribers to that event, not the poster.
Internet connectivity status (i.e. ConnectivityManager, NetworkInfo)
None of the above, as AFAIK getNetworkInfo() is not an expensive call.
Making simple HTTP requests to receive text (e.g. JSON), taking anywhere between 1000ms to 5000ms, average 2000ms.
None of the above. I'd use Retrofit or another HTTP client library that offers asynchronous options. If for some reason you absolutely have to do the HTTP I/O yourself, it would depend on how frequently this was happening. If, for example, you might fall behind because you fire off several of these in rapid succession, use onEventAsync() so they can run in parallel.
Making simple HTTP requests to load images with file sizes between 50kb to 1500kb (exact sizes are unknown to client, before making requests to server).
None of the above. Use Picasso, Universal Image Loader, or any of the other image-loading libraries, as they all have asynchronous options, and you really need those anyway for the image processing logic. If for some reason you absolutely have to do the HTTP I/O yourself, it'd follow the same rules as I described for the previous item.
Caching data to internal database (e.g. SharedPreferences, SQLite, etc).
Assuming that you're not using some wrapper library here that might offer asynchronous operation, this probably can be handled via onEventBackgroundThread(). That would also give you the advantage of ensuring serialized operation.