Hey guys i have a problem. I have a listview that is dynamically filled. Each row contain images and text, that are retrieved from a web service call ( i get image link in web service call, and I retrieve drawable after the web service call is finished ).
The question is this: If I have, let's say 200 images that I have to get, it is faster to pass every link to a thread and download the image in that thread, or should I use only one thread to get all of them? Or, is there any other possibility to obtain that images faster?
Thanks,
Arkde
With multiple Threads you reduce the risk of connection timing out causing all of your downloads to be held up. But you certainly don't want 200 threads either.
As was mentioned above, you should try to download images as necessary. I doubt your users are going to view all 200 images everytime they pop into that list.
Related
I have read a lot of SO answers asking a similar question, but I believe my question is different. I have to load around 70-80K records from the cloud and display it to the user in a ListView. A few things that I want to be done :
I don't want to use a load more Button or load more objects when the user scrolls as I have a index from A-Z so the user could start my application and click on Z and the data should be present/available to him.
I have considered pre fetching the data using a splash screen but I was wondering if there is really any other optimised method to fetch such huge data.
I don't want to hang up the UI thread with the Loading progress bar.
I agree that this may be too much to ask for but I am just trying to see if someone has a very efficient way of doing this. I am open to ideas involving modifications in the backend on web service as well, so if you have an efficient way of achieving this using some modifications on the web service, that is also fine for me.
If it helps, look at your default contacts app, it has all the data ready and available to you when you open it. You can directly use the index to navigate to Z section. Just assume the same with 70k entries in the app.
Thanks in advance!
Here is the best solutions I figured out with the help of Tamal Mukherjee and Roman Nurik.
Tamal's solution :
Just load 5-10 rows/letter. Add a 'more' button or handle scroll event and load dynamically. Use SQLite to store data. Use background threads to fill up the db.
Roman Nurik's soltuion :
With 80k rows, that's well over 1000 items per letter in the alphabet. Seems like you'll need a lot more than letter indexing to make this UI usable. Why not offer filter-as-you-type? That'll result in more HTTP requests but might result in a better UX.
So i guess my implementation will be a combination of the both.
Please follow this step:-
1- Call API on splashscreen using IntentService.
2- Use static broadCasting and save API response into sqlitedb using ORMLite in onRecieve() method of BroadCastReciever.
3- Make sure there should be separate class for receiver.
4- Use Loader Manager for updating ListView.
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.
I am having one web service in which i have list of countries, state and corresponding cities of it. Now I am little bit confused in pulling this data in my Android app. Right now I have only 2(USA,Canada) Country data with me but it might be increased in future. Also I have list of state in this country and yes the cities in every state.
I have one splash screen in my app in which I have written the logic of getting country and on the basis of that i am getting state and then cities for every state. But its long process and if i publish this a user will be frustrated by waiting time. So I don't want to use this way which takes longer time for pulling data. Is there any other way or suggestion for me to achieve this.
All suggestions are welcome.
you should use AsyncTask to perform any web data downloading (and uploading), it works in the background and does not block UI thread, so your user won't notice.
also, it might be a good idea to supply default country/city data along with your application and then download only changes/updates.
Use a Service or intent-service, to download the data in background. and when the download is complete you can display the downloaded data using onbind. service runs on a seperate thread.
You could simple use the system DownloadManager to get the files from your sources and later process them. The DownloadManager will even inform you when the file is fully downloaded.
Take a look a https://github.com/commonsguy/cw-android/blob/master/Internet/Download/src/com/commonsware/android/download/DownloadDemo.java for a simple example code using DownloadManager.
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.
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.