Using Cursor with ListView adapter for a large amount of data

六月ゝ 毕业季﹏ 提交于 2019-11-27 21:38:30
Jason L.

The reason for the slow time in loading the adapter is the internal call the CursorAdapter makes to Cursor.getCount().

Cursors in Android are lazily loaded. The results are not loaded until they are needed. When the CursorAdapter calls getCount() this forces the query to be fully executed and the results counted.

Below are a couple links discussing this very issue.

http://groups.google.com/group/android-developers/browse_thread/thread/c1346ec6e2310c0c

http://www.androidsoftwaredeveloper.com/2010/02/25/sqlite-performance/

My suggestion would be to split up your query. Load only the number of visible list items on screen. As the user scrolls load the next set. Very much like the GMail and Market applications. Unfortunately I don't have an example handy :(

This doesn't answer your question but hopefully it provides some insight :)

Not sure why setAdapter should take so long. I've done about 5000 rows much faster than that. However, I usually create an adapter without a cursor first, call setAdapter with the "empty" adapter, then kick off an asynchronous query using an AsyncQueryHandler subclass. Then, in onQueryComplete, I call changeCursor on the adapter.

Well, I can only offer you a dumb suggestion at this point - begin a query in a separate thread that will go through the entire database and create your 8000-row cursor.

In your UI thread, create a cursor where you set the limit to 100 or so, and use that for your adapter. If the user scrolls to the bottom of your list, you could add a row with a ProgressBar or indicate otherwise that there's more to come.

Once your second thread is done, replace the adapter.

Alternatively, you could have an array adapter or something similar, do a bunch of queries in the second thread with 100 rows each, and add them to your array adapter as they come in. That would also make it easier to add a dummy row at the bottom that tells users to hold their horses.

One note - I would assume it's safe to read from the database from two threads at the same time, but be careful when it comes to writing. My app had a wonderful bug where it trashed the database when I had database operations in a separate thread until I added proper locking (which you can also enable in the database).

EDIT: Of course, AsyncQueryHandler, I knew there was something like that, but I couldn't remember the name. More elegant than a separate thread, of course.

Btw - how are you storing the database? Is it just a regular database file in your internal storage?

hi im trying acheive this with for more than 50000rows. i think my code can give u the better results for u as u have only 8000 records.

1)use content provider instead of sqlite. 2)use loadermanager callbacks to load cursor asynchronously 3)for searching use FTS tables. 4)optimize ur db with indexing too.

trust me it works very fine with 8000 rows even with sectionIndexer and with fast scroll too.

let me know if u have any doubts.

P.s if u found a better solution , which u think can handle 50000 rows please let me know.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!