我正在使用自定义CursorAdapter从sqlite数据库中获取数据并在列表视图中显示它.该数据库包含2列,大约8.000行.所以我正在寻找一种方法来查询和尽快显示所有数据.我用asyncTask完成了这个是代码:
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(); }
}
除了我需要将结果设置为适配器的部分之外,这个工作正常.我做了一些时间测试,需要大约700毫秒来使它超过startManagingCursor.问题是它需要大约7秒才能超过setAdapter(结果)并且这是在UI线程中运行所以它使我的应用程序无响应(进度对话框冻结,有时会应用程序).我如何减少这个时间?我可以使这也在后台运行或以任何方式提高响应能力?
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 the name of the 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 the name of the 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()); } } }
解决方法
加载适配器的时间较慢的原因是CursorAdapter对Cursor.getCount()的内部调用.
Android中的游标被懒散加载.在需要之前不会加载结果.当CursorAdapter调用getCount()时,这会强制查询完全执行并计算结果.
以下是一些讨论这个问题的链接.
http://groups.google.com/group/android-developers/browse_thread/thread/c1346ec6e2310c0c
http://www.androidsoftwaredeveloper.com/2010/02/25/sqlite-performance/
我的建议是拆分你的查询.仅加载屏幕上可见列表项的数量.当用户滚动加载下一组时.非常像GMail和市场应用程序.不幸的是我没有一个方便的例子:(
这不能回答你的问题,但希望它能提供一些见解:)