I am attempting to implement an "infinite" scroll type of feature in my app. The feature will display a list of items. Each item will contain images, text, etc. When the user scrolls down, more items will appear. I would like to know how "cacheing" algorithms works in popular apps and what is the recommended way to implement them.
The problem that I am having is that if the user visibly goes through 100 items, a lot of in-app Memory is used up. This causes the app to crash after seeing many items. I'm convinced that I should store some of these assets onto the File System of the phone and then re-use them once it's seen again. Please correct me if I am wrong.
For example:
Facebook
In the News Feed, as I scroll down, many "news items" contain images/videos/text. If I scroll through 20, everything looks great. As I scroll down quickly to the "bottom" of the news feed after >40 items, it appears to halt for a split second to "load" more items.
Then, when I scroll back up the news feed, it will display the previously viewed items fairly quickly. I guess my question is, are only a limited # of items cached in memory and most items cached on the file system?
How does it work? I assume when the user sees new news feed items , the app must "download" the assets from the Facebook Server. However, if these items become un-visible, and then the user scrolls back to these items, are these items re-downloaded, retrieved from memory cache, or retrieved from file cache?
Related
Much Application is a chat program like whatsapp. So it doesn't need to display all the messages at once. Only the last messages should be shown to the user at the startup unless user scrolls and view the past ones.
I have a ScrollView that contains a large (around 1000) amount of elements(messeges). So its not much efficient performance-wise because it loads and displays all the elements at once.
In most cases its useless that it loads the entire history of msgs.
(I have think of splitting these msgs into sections and manually choosing to load them only too)
Is this functionality provided built-in with ListView or RecycleView.
I mean though we load all the elements to ListView, does it have a capability to intelligently process the elements that are shown in the screen in a particular time (or scroll level) ?
Yes, the main reason of using ListView or RecyclerView is that they provide you with View re-use. It won't load all the child-Views in one go: it will ask you to bind your data to a View whenever needed.
Is this functionality provided built-in with ListView or RecycleView.
I mean though we load all the elements to ListView, does it have a capability to intelligently process the elements that are shown in the screen in a particular time (or scroll level) ?
Yes, that's exactly what ListView does. It will be slower to scroll with it, but it will take just the necessary amount of memory.
I'm building an Android magazine-reader for our campus publication that pulls articles from a web service and displays them in a ViewPager.
To minimize the initial loading time, I want it to pull a relatively small number of articles (say 10) to begin with. Once it has pulled and displayed those articles, I want it to immediately begin downloading/deserializing the next 10 articles while the user is looking through the first set. Likewise, when they reach the 11th article I want it to go ahead and download the next 10, so that the user can continually browse without ever having to wait for more articles to load. This seems easy enough to accomplish using AsyncTasks, but I've hit one small hitch: When the next set of articles is downloaded and added to the ViewPager, it jumps back to displaying the first page.
How can I add views to the end of the ViewPager's dataset without changing the article being displayed to the user?
you will want to use the Endless Adapter created commonsware.
Or you can open the page again after refreshing the content of the ViewPager. Get the article id of the article user is reading. Open the same article after the ViewPager is refreshed.
I've got one issue with otherwise nice working ListView.
I want to load new items into the existing listView, just like in Gmail or Google Play app - I show like 15 items and when the user clicks Load next, the other 15 will be loaded, so we will display like 30 items.
Everything works fine like this, except the ImageView, which is part of the every item in the ListView and is loaded asynchronously. Every time I click load next, all the images in the existing items are reloaded.
How can I avoid this behavior? Any suggestions?
It doesn't really look well, images are loaded from the cache really fast, so it is like a short blicking of all the images.
I was thinking about overriding the notifydatasetchanged() somehow - but I would expect a method in the ListView, in which I could set whether the whole ListView should be reloaded, or just the new items.
All the items will fill_parent, so the width is not an issue.
Today I was thinking about how Android framework works, and I'm not sure about one thing - how developer (me) should program lists to show custom data from few sources. I created few apps, but its important to me to keep my applications clean and fast as possible.
So - I have an app, for example news reader. Im using Fragments, ListFragments, custom layouts for list items and BaseAdapter for showing data in many lists and activities. Nothing new here, and nothing special. At first I download all data from webserver to sqlite in app, so Im sure about it speed and stability. And then what's next?
Should i create List items from Java Lists (List items) and then pass it to baseadapter, or I should only use way SQLite Cursor->list item? What is better to refresh list, add new items and delete them? Remember that i have my ListFragment with baseadapter in separate class.
Im not sure about it, so I clearly dont know how should i refresh and load new items to my list. I just want to keep app clean, without many 3rd party libraries (so i dont care about EndlessList or something like that).
tl;dr
How should I create list for speed purposes, when i use few sources to show data?
I'm not sure whether I understand your full question but about the part which data source to use for an Adapter, here are my thoughts:
I think that depends on the amount of data you are dealing with. If it is sufficiently small you can keep everything in a List in memory, but you also need to be sure that the data won't grow over time.
Using a Cursor as a data source is unfortunately also not a safe option for getting around a possible "Out Of Memory" exception problem. There is a limit per query because of the implementation of the cursor which apparently loads the whole result set into memory.
So if you are dealing with a lot of data or data that potentially grows over time (like messages, user-created items), you need to have an Adapter that internally works with a data window which loads a fixed amount of items into memory at a time. That window always keeps a bunch of items in memory which can be currently viewed and quickly reached with the ListView (by scrolling up and down).
Let's say that window holds for example 200 items.
When the upper / lower bound of that window is reached the Adapter needs to load the next adjacent window. You can observe that kind of behavior in the GMail app ("Loading conversations....").
I would let that data sit in the cursor and not transfer it to a list first, because you can use the cursor like a list.
I'm new to Android programming. I wonder how many items a ListView can store? I search in docs but they don't talk about this. What if I put a lot (maybe 10k) items into a ListAdapter, will it affect to the performance?
Cheers,
MK.
The ListView is virtualized in Android. Practically speaking, that means that there's no actual limit for the number of elements inside it. You can put millions of rows inside the list and it'll only allocate memory for the currently visible ones (or a few more tops).
Check out the dozens of tutorials regarding writing a custom Adapter class for an AdapterView (ListView extends that). Also check out the Google I/O 2010 session on ListViews; it's really useful: here
There's no limit as the ListView only renders items when they come into view, and so only cares about the data for the ListView when it comes to render the item (though it needs to know the quantity of items to render the scrollbar correctly)
The Google IO video really is great for learning about ListView
http://www.youtube.com/watch?v=wDBM6wVEO70
That said, I'd ask whether you SHOULD load that many, as clearly the user cannot look at them all and scrolling around a ListView with that many items will be very tedious. If it was me I'd be asking some questions:
Does the list need to show them ALL initially? Can it just show the most relevant set? The nearest/biggest/smallest/best/etc
Rather than load them all at once, can you load blocks in pages of items? So for example you load 10-100 initially, and when the user gets to the bottom show "Loading more..." with a progress spinning icon, and pull more in, then the user can choose how many to load, and how much scrolling they are prepared to do
Should you be building a UI to filter the items so there's never a need for them to look at 10,000?
More on ListView
http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
http://developer.android.com/guide/topics/ui/binding.html
http://www.androidguys.com/2008/07/14/fancy-listviews-part-one/
Integer.MAX_VALUE since most of its functions will break as they rely on int position.
I created a ListView and used Integer.MAX_VALUE as the number returned to the adapter for the number of items in the list. This had no effect on the performance of the ListView even though it was holding about 2 billion items.
I think 10k will work :P
Check out my answer here to see in detail what I mean : How to create a closed (circular) ListView?
You have a memory limit (which is device specific). As long as you don't exhaust your memory limit, you can store as many items as you wish. There are ADT tools that you can use to monitor how much memory your application is using at any moment.