I'm new to Android programming and I have a threading issue.
I'm basically populating a GridView with images from 50 or so URLs, but those URLs will not be known until I retrieve a JSON object from an already known URL. I know that I have to fire off a bunch of threads for each URL download (using the AsyncTask class).
How can I effectively queue these threads so that the JSON thread is executed and finished first, so I can use data retrieved from that thread when I fire off those 50 image threads immediately after?
Do not start 50 threads. Use a single thread. While this should be separate from the UI thread for responsiveness, there is no need to spawn multiple threads, and certainly not one thread per URL.ce
Simply make your JSON network call, then parse the response, then (in the same thread) loop through the URLs requesting each one, and decoding the result into a Bitmap. You'd them add them within some model object to the Adapter for your GridView, which would automatically trigger the GridView to update on the UI thread.
There are better practices here, such as lazy loading, caching, and displaying a placeholder image while images are loading, but the exact implementation becomes too complex to describe here. Search for WeakReferenceMap and LruCache to find examples of the best practices for dynamic image loading into an AdapterView.
Well, you could just run the first fetch and when this is done, fire the 50 threads from this main thread. As Android 3.0 and later will kill your app when you do network communication from the UI thread, an AsyncTask could be a way for to fetch the JSON. When this returns it could fire the other threads.
One thing you should still consider is that Android is, as powerful as it is, still a device with limited capabilities. 50 Threads may use more resources that the target handset has and thus your app may be killed by the system (e.g. because of OOME). So wile on a desktop 50 threads don't sound much, they are much on a phone.
Also IIrc, there is a limit in the http spec, that one may only have 4 (?) simultaneous connections to one remote server. So consider queuing up the image loading requests and fetching them one after the other.
Related
I've an android app where I'm retrieving data into a Fragment. And I believe that Firebase manages its asynchronous calls. But still I've doubt the if we need to write the Firebase code in the background thread or not?.
If we need to write it into the background thread then can you please tell which operations takes more time. eg:
mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");
I think that performing this on the main UI thread may become risk full because setting connection between database may sometime take large time.
The Firebase Database client performs all network and disk operations off the main thread.
The Firebase Database client invokes all callbacks to your code on the main thread.
So network and disk access for the database are no reason to spin up your own threads or use background tasks. But if you do disk, network I/O or CPU intensive operations in the callback, you might need to perform those off the main thread yourself.
If you're pulling down a large-ish collection of data from the database, and you want to convert that all into a JavaBean type collection, you may want to offload that onto another thread as the size of data its use of reflection may cause too much work for the main thread. The only way to know about this for sure is to benchmark it yourself. Generally speaking, you get 16ms to do things on the main thread before you start dropping from the optimal rendering speed of 60 frames per second.
I recently tweeted a diff on a project of mine where I refactored a pattern for sending database listener to an Executor for background processing. However, your app may not call for this kind of complexity. It was good for my app, however. https://twitter.com/CodingDoug/status/773277680867258368
Firebase runs all of its callbacks asynchronously as documented https://www.firebase.com/docs/android/guide/retrieving-data.html . This is done through a web socket layer.
If for example, you need to do a large amount of data processing on the result of the Firebase data update - you should probably spin up an AsyncTask to prevent the UI from blocking. This isn't any different from how you would normally approach data processing before being presented to the UI.
The Firebase documentation covers how data is handled and the reason why you do not need to execute any background reads. You should probably spend some time reading the documentation.
I have some issues figuring out the use of aSynctask, threads and downloading images. I've made a class that downloads image but doesn't implement any thread, asynctask or whatsoever.
At the moment i'm only using one asynctask to accomplish steps 1 and 2. This takes around 10 seconds with my tablet.
I have thought of 3 steps how the application would work/proceed.
Download the most important information from url, which is in JSON format and save it into sqlite database. This is the most relevant information that other steps need to have, in order to proceed. This takes around 2 seconds at most at the moment and I am saving this into database.
Query into my database to get more urls from the previous JSON data and download even more information from the same site (30 different URL's) and save the JSON into my database. This takes around 5 seconds at the moment within the single asynctask. I was thinking about separating this into 3(?) threads if possible.
Query database again to get information that step 2 provided and download approx 200 from different URLS, images that are of size ~150px and save these images to device storage. All of the previous steps have to be done before I can do the downloading. This has to be split up into multiple threads also so I can download as many images fast as possible.
I was wondering what would be the smartest way to use asynctask for this task and the separate threads. How many threads would you think that I would have to use (of course, I'll figure this out later on when I'm optimizing). Should I first use the asynctask to download step 1 and on post execute start the other threads? Should I create the other threads within this class that has nested async class.
Thanks a lot at least for reading all this and possibly for your help.
Edit: oh I'm using a service to start the asynctask.
The only reason to make multiple threads downloading different images is if server would take some time to query for the image and as a result you are idling and not actively pumping data. But if it is not the case then your device is working as fast as your connection allows you. Hope it makes sense.
If I need to asynchronously load some data via HTTP (or whatever) in order to update the UI, I have a few options when writing an Android application (among many others that I'm sure I missed):
Use a regular thread and a handler to update the UI.
AsyncTask
Use and IntentService, and use either a callback or broadcast the results via an Intent.
Using Loaders.
From what I understand, an IntentService is not tied to an Activity's lifecycle, so any changes to orientation, etc, will not impact the retrieval of data. Where this is not the case for an AsyncTask or thread fired off within an Activity.
The reason for the question, is that I just recently read about Loaders, and am confused as to their application. They seem to be more closely tied to a data source, where if the data source changes, then "transparently" everything is handled appropriately. Loaders also appear to be tolerant to configuration/orientation changes (I believe).
I've been currently using an IntentService to make RESTful service calls, and broadcasting the results to be received by appropriate Activities.
I'm assuming I could write an HTTP based Loader, but I'm not sure if this is the best use of this mechanism.
What are the advantages/disadvantages to using one of the async data loading methods over any other?
All of these mechanisms are simply options. There's no such thing as a one size fits all tool and so all of these different methods of completing the same task is a way to cover as many use cases as possible.
Ultimately, it's up to you to decide which method makes more sense for your scenario. But for a sort of generic explanation of what you should use...
Regular thread and a handler - Why when there are other, simpler, options?
AsyncTask - Since an AsyncTask will almost always depend on an Activity, use this when you need to load data asynchronously and you are 100% certain of how long it may take. Example: Executing an SQLite query.
IntentService/Service - Services are not bound to an Activity like an AsyncTask is, therefore, they are perfect for scenarios in which you may not know how long it will take to complete. Example: Downloading data from a web API and updating a database.
Loaders - Loaders are aimed at simplifying the process of loading data and populating it into UI. The nature of Loaders sort of assumes that the data you will be loading will be presented to the user as a list of some sort. Example: Downloading data and populating it into a ListView
I am working on a project where i need to hit a web service download the data which is JSON and will be represented in a list. And all the list items have there thumbnail url's which would be downloaded and displayed in the list item.
I have done the entire calling part with both a ThreadPoolExecutor and a AsyncTask.
But from a design perspective which is a better option out of:
1. ThreadPoolExecutor
2. AsyncTask
Few adv. of ThreadPoolExecutor:
1. User can define no. of concurrent threads that can be executed.
2. Cancelling all the request at once.
Few adv. of AsyncTask:
1. Internally it uses a ThreadPoolExecutor, however we cant define no. of threads that run simultaneously.
2. Cancelling a single request is easy.
3. Ability to attach and detach a task.
4. Updating the UI from doInBackground is simple.
I know more advantages of AsyncTask, however for a simple application like fetching data from a web service and later on fetching images.
Which would be more appropriate a AsyncTask or ThreadPoolExecutor? If you can provide a few reasons regarding your choice it would be helpful.
I have read a few article here on SO but none that compares the two. If there are any that i missed sorry for the trouble could you please post me the link for the same.
Thanks in advance.
I consider that AsyncTask is useful if you want to load thumbnail using a series "cascade-call": in the onPostExecute, you can start the next AsyncTask to download the next thumbnail.
But if you want to improve efficiency, I suggest using ThreadPoolExecutor. This is a sentence from developer.android.com:
Thread pools address two different problems: they usually provide
improved performance when executing large numbers of asynchronous
tasks, due to reduced per-task invocation overhead, and they provide a
means of bounding and managing the resources, including threads,
consumed when executing a collection of tasks. Each ThreadPoolExecutor
also maintains some basic statistics, such as the number of completed
tasks.
In conclusion, ThreadPoolExecutor was probably designed for cases such as your; for this reason, I suggest you this class.
I am making a list of view in my application that shows all installed applications in the users device. It shows the name and the icon. The list view takes very long to load and the UI is unresponsive while its loading. I have seen the resources that have lazy load and async task tutorials but they all seem to fetch images from the internet. I need to lazy load images that are in the system (which are the application icons). I dont know how to do this with async task either. Can someone please help me lazy load or asynctask application icons. This is a very essential part of my application and i would deeply appreciate it. Thanks.
So I usually don't offer advice if there isn't any clear attempt/code to show for, but I remember when I was first confronted with AsyncTasks and threading in general and how it was a bit confusing at first, so I'll get you started on the right track.
So an AsyncTask basically runs a process that may take a while (such as loading information from a server or, in your case, fetching files). It has a couple methods that are detailed here, but I believe, for your scenario, you will simply need to use the doInBackground and onPostExecute methods. What you'll probably be doing in each of those is getting the actual images and data for your ListView in doInBackground and then updating the ListView to display that data in onPostExecute. Consider the examples outlined here. Essentially, the doInBackground method will send some data (in this case your files and other stuff - usually in a form of an array or List or something if there's lots of data being sent) to the onPostExecute method which will handle the data from there.
What's happening is that you're overburdening your main UI thread and the program will wait for the fetching and loading of the images intermittently with your UI. AsyncTask takes care of this for you by throwing all the work to separate worker threads. Problems usually arise when overburdening the UI thread, such as your program closing unexpectedly because Android notices that the main application thread is using too many resources (no actual bugs in your code).
As for the Lazy Load of the image data, I'm not completely sure how it works (never had to use it), but this seems really helpful.
Hope that gave you some direction.