我正在尋找一種解決方案來加速更新我的spinners。目前,我正在使用SimpleCursorAdapter,每當更改基於先前選定的微調器的搜索條件時調用ChangeCursor。Android - SimpleCursorAdapter changeCursor函數太慢
我做了一些時間測試,查詢需要5ms到60ms,而changeCursor函數需要600ms到4000ms +。是否有另一種方法更新適配器上的光標更快?我沒有使用相同的查詢,所以我不能簡單地重新查詢遊標,然後調用notifydatasetchanged。我必須創建一個新的查詢,然後返回一個新的光標(也許有更好的方法來做這個部分)。
這裏是我當前如何填充
private void writerSpinner() {
String[] columns = new String[] { Passage.COL_WRITER_ID + " " + BaseColumns._ID, Passage.COL_WRITER_NAME };
String whereClause = null;
String groupBy = null;
String orderBy = Passage.COL_WRITER_ID + " ASC";
if (mAdapterPassage == null) {
String[] columnsSpinner = new String[] { Passage.COL_WRITER_NAME };
int[] to = new int[] { android.R.id.text1 };
mAdapterPassage = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_spinner_item, null, columnsSpinner, to);
mAdapterPassage.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mPassage.setAdapter(mAdapterPassage);
mPassage.setOnItemSelectedListener(onItemSelectedListener);
}
AsyncLoadData loadData = new AsyncLoadData(mAdapterPassage, mPassage, Passage.TABLE_NAME_WRITERS, columns, whereClause, groupBy, orderBy);
loadData.execute();
}
private void updateChapterSpinner() {
String[] columns = new String[] { Passage.COL_WRITER_ID + " " + BaseColumns._ID, Passage.COL_CHAPTER_ID };
String whereClause = Passage.COL_WRITER_ID + " = " + mSelectedWriterId;
String groupBy = Passage.COL_CHAPTER_ID;
String orderBy = Passage.COL_CHAPTER_ID + " ASC";
if (mAdapterChapter == null) {
String[] columnsSpinner = new String[] { Passage.COL_CHAPTER_ID };
int[] to = new int[] { android.R.id.text1 };
mAdapterChapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_spinner_item, null, columnsSpinner, to);
mAdapterChapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mChapter.setAdapter(mAdapterChapter);
mChapter.setOnItemSelectedListener(onItemSelectedListener);
}
AsyncLoadData loadData = new AsyncLoadData(mAdapterChapter, mChapter, Passage.TABLE_NAME_PASSAGES, columns, whereClause, groupBy, orderBy);
loadData.execute();
}
private void updateVerseSpinner() {
String[] columns = new String[] { Passage.COL_WRITER_ID + " " + BaseColumns._ID, Passage.COL_VERSE_ID };
String whereClause = Passage.COL_WRITER_ID + " = " + mSelectedWriterId
+ " AND " + Passage.COL_CHAPTER_ID + " = " + mSelectedChapter;
String groupBy = Passage.COL_VERSE_ID;
String orderBy = Passage.COL_VERSE_ID + " ASC";
if (mAdapterVerse == null) {
String[] columnsSpinner = new String[] { Passage.COL_VERSE_ID };
int[] to = new int[] { android.R.id.text1 };
mAdapterVerse = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_spinner_item, null, columnsSpinner, to);
mAdapterVerse.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mVerse.setAdapter(mAdapterVerse);
mVerse.setOnItemSelectedListener(onItemSelectedListener);
}
AsyncLoadData loadData = new AsyncLoadData(mAdapterVerse, mVerse, Passage.TABLE_NAME_PASSAGES, columns, whereClause, groupBy, orderBy);
loadData.execute();
}
private class AsyncLoadData extends AsyncTask<Void, Void, Void> {
String mTableName;
String[] mColumns;
String mWhereClause;
String mGroupBy;
String mOrderBy;
Spinner mSpinner;
Cursor mCursor;
SimpleCursorAdapter mAdapter;
public AsyncLoadData(SimpleCursorAdapter adapter, Spinner spinner, String tableName, String[] columns, String whereClause, String groupBy, String orderBy) {
mAdapter = adapter;
mSpinner = spinner;
mTableName = tableName;
mColumns = columns;
mWhereClause = whereClause;
mGroupBy = groupBy;
mOrderBy = orderBy;
}
@Override
protected void onPreExecute()
{
//mSpinner.setVisibility(View.GONE);
}
@Override
protected Void doInBackground(Void... arg0) {
long startCursor = new Date().getTime();
mCursor = mDBHandler.query(mTableName, mColumns, mWhereClause, null, mGroupBy, null, mOrderBy);
long timeToQuery = new Date().getTime() - startCursor;
Log.i("CursorQuery", "Time to Query Cursor " + mGroupBy + ": " + timeToQuery + "ms");
return null;
}
@Override
protected void onPostExecute(Void result)
{
long startAdapter = new Date().getTime();
mAdapter.changeCursor(mCursor);
long timeToChangeCursor = new Date().getTime() - startAdapter;
Log.i("AdapterQuery", "Time to Change Cursor " + mGroupBy + ": " + timeToChangeCursor + "ms");
mAdapter.notifyDataSetChanged();
//mSpinner.setVisibility(View.VISIBLE);
}
}
private OnItemSelectedListener onItemSelectedListener = new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch(parent.getId()) {
case R.id.bible_passage:
mSelectedWriterId = position + 1;
updateChapterSpinner();
break;
case R.id.bible_chapter:
mSelectedChapter = position + 1;
updateVerseSpinner();
break;
case R.id.bible_verse:
mSelectedVerse = position + 1;
break;
}
}
public void onNothingSelected(AdapterView<?> parent) {
}
};
刪除'mAdapter.notifyDataSetChanged();'行,因爲'changeCursor()'方法在其實現中調用'notifyDataSetChanged()',因此它是無用的。你確定你得到這些加載值?嘗試使用traceview來查看問題出在哪裏。 – Luksprog
@Luksprog對不起,在代碼中沒有問題,它都按預期運行。它不是很快。 changecursor需要1/2到4秒的時間來更改我的遊標適配器中的數據,這是不可取的。我正在尋找更快的解決方案。 – DMCApps
我並不是說代碼不正確(但該行無用)。我沒有看到另一種方法來更新'Cursor'('swapCursor',但不應該有區別)。使用traceview查看瓶頸在哪裏。此外值得一提的是,如果您僅在某些API級別上測試並看到此問題,或者它是一般性的。 – Luksprog