4

我尝试使用 db 表的数据填充建议列表。但是我得到StaleDataException了。它非常随机地抛出,但总是当我在文本视图中输入一个字符时。

这是我的代码:

CursorLoader 扩展CristianSimpleCursorLoader

public class TagCursorLoader extends SimpleCursorLoader {

    private String mSelection;
    private TagDbLoader mDbLoader;

    public TagCursorLoader(Context context, TagDbLoader dBLoader, String selection) {
        super(context);
        this.mDbLoader = dBLoader;
        this.mSelection = selection;
    }

    @Override
    public Cursor loadInBackground() {
        return mDbLoader.fetchContainingString(mSelection);
    }

}

加载器回调:

public class TagCursorLoaderCallback implements LoaderCallbacks<Cursor>, CursorToStringConverter {

    private Context mContext;
    private TagDbLoader mdDbLoader;
    private SimpleCursorAdapter mAdapter;
    private String mSelection;

    public TagCursorLoaderCallback(Context context, TagDbLoader dBLoader, SimpleCursorAdapter adapter) {
        this.mContext = context;
        this.mdDbLoader = dBLoader;
        mAdapter = adapter;
        mSelection = "";
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new TagCursorLoader(mContext, mdDbLoader, mSelection);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

        if (!data.isClosed()) {
            mAdapter.swapCursor(data);
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }

    public void setSelection(String mSelection) {
        this.mSelection = mSelection;
    }

    @Override
    public CharSequence convertToString(Cursor cursor) {
        return cursor.getString(cursor.getColumnIndexOrThrow(DbConstants.Tags.KEY_TAG));
    }

}

最后,当我设置AutoCompleteTextView

private void initializeAutoComplete() {

        mTagDbLoader = new TagDbLoader(getActivity());
        mTagDbLoader.open();

        mTagInput = (AutoCompleteTextView) mLayout.findViewById(R.id.autoComplete);

        mTagInput.addTextChangedListener(new TextWatcherAdapter() {

            @Override
            public void afterTextChanged(Editable s) {
                mLoaderCallback.setSelection(s.toString());
                getLoaderManager().restartLoader(0, null, mLoaderCallback);
            }
        });

        mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1,
                null, new String[] { DbConstants.Tags.KEY_TAG }, new int[] { android.R.id.text1 },
                0);

        mLoaderCallback = new TagCursorLoaderCallback(getActivity(), mTagDbLoader, mAdapter);
        mAdapter.setCursorToStringConverter(mLoaderCallback);
        mTagInput.setAdapter(mAdapter);
        getLoaderManager().initLoader(0, null, mLoaderCallback);
    }
4

1 回答 1

6

经过一番调查,似乎SimpleCursorAdapter继承自ResourceCursorAdapter,继承自CursorAdapterCursorAdapter用于CursorFilter过滤,这个类调用changeCursor()它的publishResults(). changeCursor关闭旧光标...这就是我的光标自动关闭的原因。

我删除了加载器,并将实现更改为下面的代码,并且效果很好:

mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1,
                mTagDbLoader.fetchAll(), new String[] { DbConstants.Tags.KEY_TAG },
                new int[] { android.R.id.text1 }, 0);

mAdapter.setFilterQueryProvider(new FilterQueryProvider() {

    @Override
    public Cursor runQuery(CharSequence constraint) {

        if (constraint == null || constraint.equals(""))
            return mAdapter.getCursor();

        return mTagDbLoader.fetchContainingString(constraint.toString());
    }
});

mAdapter.setCursorToStringConverter(new CursorToStringConverter() {

    @Override
    public CharSequence convertToString(Cursor c) {

        return c.getString(c.getColumnIndexOrThrow(DbConstants.Tags.KEY_TAG));
    }
});
于 2013-08-04T13:37:10.197 回答