gpt4 book ai didi

Android - SimpleCursorAdapter changeCursor 功能太慢

转载 作者:太空狗 更新时间:2023-10-29 12:49:15 26 4
gpt4 key购买 nike

我正在寻找一种解决方案来加快我的微调器的更新速度。目前我正在使用 SimpleCursorAdapter 并在我根据先前选择的微调器更改搜索条件时调用 ChangeCursor。

我做了一些计时测试,查询需要 5 毫秒到 60 毫秒,而 changeCursor 函数需要 600 毫秒到 4000 毫秒以上。是否有另一种方法可以更快地更新适配器上的光标?我没有使用相同的查询,所以我不能简单地重新查询游标然后调用 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) {

}
};

最佳答案

问题

changeCursor 花费这么长时间的原因是返回的游标Database.query(...) 只在必要时初始化(所以它是游标的错误,而不是适配器的错误)。

游标初始化缓慢的原因是它解析一次整个结果集(因为它需要知道总数)。尽管 SQLite 非常快地返回大量查询,但 java 非常慢解析它们(比 SQLite 慢 100 到 1000 倍)。

解决方案

进来,HugeSQLiteCursor (with JavaDoc!)。我写了这个游标来解决这个问题。它加载结果递增地和自动地,而不是一次全部(用一个聪明的找出开销几乎为 0 的总计数的解决方法)。

Download the .jar file ,将它添加到您的 libs/ 文件夹,然后执行以下操作使用它(完全限定名称是 com.malabarba.hugesqlitecursor.HugeSQLiteCursor):

adapter.changeCursor(new HugeSQLiteCursor(db, stepSize,
table, columnFields,
selection, selectionArgs));

如您所见,由于结果是延迟加载的,因此您需要将数据库和查询参数传递给构造函数。创建后,游标应该在任何情况下都能完美运行以前使用 SQLiteCursor。

第二个参数(stepSize),是你想要的项目数在创建游标时初始加载。 这很重要参数

整个游标的初始化时间实际上是就好像它只有 stepSize 结果一样。但是不要让 stepSize 小于一个屏幕中的结果数。

这个 Cursor 有效地消除了“Java 太慢”的瓶颈。在我的 Nexus 4 上,它在不到 60 毫秒 的时间内返回 50.000 个结果的查询,而 SQLiteCursor 则需要大约 1000 毫秒。当然,如果您的查询非常庞大,以至于 SQLite 返回结果的速度也很慢,那么此游标只能帮助您到此为止。

关于Android - SimpleCursorAdapter changeCursor 功能太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14261424/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com