Displaying 100,000 objects in ListView from SQLite database
I am trying to display all items from a pre-populated database (with over 100,000 rows) in a ListView using cursors. It works, but it takes a few minutes to start the app and display the ListView. Is there a faster way? I read something about FTS3 tables, does this help?
I am using ArrayList<HashMap<String, String>>
with SimpleAdapter and a custom two line layout. Code:
Cursor cursor = sDictionary.query("FTSgesla", new String[] {PodatkovnaBaza.KEY_WORD, PodatkovnaBaza.KEY_DEFINITION}, null, null, null, null, PodatkovnaBaza.KEY_WORD);
if (cursor == null)
{
// There are no results
mTextView.setText("Empty");
}
else
{
HashMap<String, String> item;
if(cursor.moveToFirst())
{
do
{
item = new HashMap<String, String>();
item.put("line1", cursor.getString(0));
item.put("line2", cursor.getString(1));
list.add(item);
}
while(cursor.moveToNext());
}
sa = new SimpleAdapter(GlavniActivity.this, list,
R.layout.result,
new String[] { "line1","line2" },
new int[] {R.id.word, R.id.definition});
mListView.setAdapter(sa);
// Define the on-click listener for the list items
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//do something
}
});
}
There is no faster way to download 100,000 items, and your user also won't need to see everything at once, hence download them one by one using a stream.
private class SQLTask extends AsyncTask<Integer, String[], Integer> {
@Override
protected Integer doInBackground(Integer... params) {
db.open();
Cursor c = db.getAllDataCursor();
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
String[] temp = new String[c.getColumnCount()];
for (int i = 0; i < temp.length; i++) {
temp[i] = c.getString(i);
}
publishProgress(thisTask, temp);
}
c.close();
db.close();
}
@Override
protected void onProgressUpdate(String[]... values) {
super.onProgressUpdate(values);
// LOAD ONE ROW
}
}
It should be in sections with some kind of filtering, loading that many elements just seem excessive.
I'm not very sure, but I'm afraid your problem is that you are downloading 100,000 views at the same time. Personally, I would use an ArrayAdapter or a base adapter, override the getView (..) method and of course with the ViewHolder template.
Here you have a very smooth and fast example using BaseAdapter: https://github.com/Jachu5/RSS_Feeder_Android/tree/master/RssFeeder_sherlock/src/com/example/adapter
Hope it helps!
Why are you loading 100k items into a list? Listview is a display element that the user will interact with. Nobody will ever scroll 100K items. Nobody will be able to scroll 1% of this. The answer here is don't download them all.