android - Using Cursor with ListView adapter for a large amount of data -
i using custom cursoradapter data sqlite database , show in listview. database contains 2 columns 8.000 rows. looking way query , show data fast possible. have done asynctask here code:
private class prepareadapter extends asynctask<void,void,customcursoradapter > { @override protected void onpreexecute() { dialog.setmessage("wait"); dialog.setindeterminate(true); dialog.setcancelable(false); dialog.show(); log.e("tag","posle nov madapter"); } @override protected customcursoradapter doinbackground(void... unused) { cursor cursor = mydbnameshelper.getcursorquerywithallthedata(); madapter.changecursor(cursor); startmanagingcursor(cursor); log.e("time","posle start managing cursor" + string.valueof(systemclock.elapsedrealtime()-testtime)+ " ms"); testtime=systemclock.elapsedrealtime(); madapter.initindexer(cursor); return madapter; } protected void onpostexecute(customcursoradapter result) { tabfirstview.this.getlistview().setadapter(result); log.e("time","posle adapterset" + string.valueof(systemclock.elapsedrealtime()-testtime)+ " ms"); testtime=systemclock.elapsedrealtime(); dialog.dismiss(); }
}
this works except part when need set result adapter. have done time tests , takes aprox 700 ms make past startmanagingcursor. problem takes 7 seconds make past setadapter(result) , running in ui thread makes app unresponsive (the progress dialog freezes , app). how make time less? can make run in background or way increase responsiveness?
tnx.
public class customcursoradapter extends simplecursoradapter implements onclicklistener,sectionindexer,filterable, android.widget.adapterview.onitemclicklistener{ private context context; private int layout; private alphabetindexer alphaindexer; public customcursoradapter (context context, int layout, cursor c, string[] from, int[] to) { super(context, layout, c, from, to); this.context = context; this.layout = layout; } public void initindexer(cursor c){ alphaindexer=new alphabetindexer(c, c.getcolumnindex(databasenameshelper.column_name), " abcdefghijklmnopqrstuvwxyz"); } @override public view newview(context context, cursor cursor, viewgroup parent) { cursor c = getcursor(); final layoutinflater inflater = layoutinflater.from(context); view v = inflater.inflate(layout, parent, false); int namecol = c.getcolumnindex(databasenameshelper.column_name); string name = c.getstring(namecol); /** * next set name of entry. */ textview name_text = (textview) v.findviewbyid(r.id.name_entry); if (name_text != null) { name_text.settext(name); } int favcol = c.getcolumnindex(databasenameshelper.column_favourited); int fav = c.getint(favcol); int idcol = c.getcolumnindex(databasenameshelper.column_id); button button = (button) v.findviewbyid(r.id.button01); button.setonclicklistener(this); button.settag(c.getint(idcol)); if(fav==1){ button.setvisibility(view.invisible); } else button.setvisibility(view.visible); return v; } @override public void bindview(view v, context context, cursor c) { int namecol = c.getcolumnindex(databasenameshelper.column_name); string name = c.getstring(namecol); /** * next set name of entry. */ textview name_text = (textview) v.findviewbyid(r.id.name_entry); if (name_text != null) { name_text.settext(name); } int favcol = c.getcolumnindex(databasenameshelper.column_favourited); int fav = c.getint(favcol); button button = (button) v.findviewbyid(r.id.button01); button.setonclicklistener(this); int idcol = c.getcolumnindex(databasenameshelper.column_id); button.settag(c.getint(idcol)); // log.e("fav",string.valueof(fav)); if(fav==1){ button.setvisibility(view.invisible); } else button.setvisibility(view.visible); } @override public int getpositionforsection(int section) { return alphaindexer.getpositionforsection(section); } @override public int getsectionforposition(int position) { return alphaindexer.getsectionforposition(position); } @override public object[] getsections() { return alphaindexer.getsections(); } @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { log.e("item click", arg1.tostring()+ " position> " +arg2); } @override public void onclick(view v) { if(v.getid()==r.id.button01){ //log.e("button click", v.tostring()+ " position> " +v.gettag().tostring()); v.setvisibility(view.invisible); databasenameshelper dbnames = new databasenameshelper(context); dbnames.setfavouritesflag(v.gettag().tostring()); } } }
the reason slow time in loading adapter internal call cursoradapter makes cursor.getcount().
cursors in android lazily loaded. results not loaded until needed. when cursoradapter calls getcount() forces query executed , results counted.
below couple links discussing issue.
http://groups.google.com/group/android-developers/browse_thread/thread/c1346ec6e2310c0c
http://www.androidsoftwaredeveloper.com/2010/02/25/sqlite-performance/
my suggestion split query. load number of visible list items on screen. user scrolls load next set. gmail , market applications. unfortunately don't have example handy :(
this doesn't answer question provides insight :)
Comments
Post a Comment