我正在使用自定义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和市场应用程序.不幸的是我没有一个方便的例子:(
这不能回答你的问题,但希望它能提供一些见解:)