java.lang.IllegalStateException:尝试重新打开已经关闭的对象:SQLiteQuery

所以我有这个奇怪的错误.我正在使用简单的游标适配器来建议searchView和数据库.我不需要内容提供商,所以我没有使用它.问题是我没有在我的代码中的任何地方关闭我的数据库或光标的命令,但我仍然收到此错误.错误:java...

所以我有这个奇怪的错误.我正在使用简单的游标适配器来建议searchView和数据库.我不需要内容提供商,所以我没有使用它.问题是我没有在我的代码中的任何地方关闭我的数据库或光标的命令,但我仍然收到此错误.
错误:

    java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id as _id, title as suggest_text_1, subTitle as suggest_text_2, imgUrl as suggest_icon_1, searchID as suggest_intent_data_id FROM suggestions WHERE (title like ? ) ORDER BY title asc  LIMIT 10
        at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
        at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
        at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
        at android.support.v4.widget.CursorAdapter.getItemId(CursorAdapter.java:225)
        at android.widget.AdapterView.rememberSyncState(AdapterView.java:1199)
        at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:815)
        at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6117)
        at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
        at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
        at android.support.v4.widget.CursorAdapter.swapCursor(CursorAdapter.java:347)
        at android.support.v4.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:326)
        at android.support.v4.widget.CursorAdapter.changeCursor(CursorAdapter.java:315)
        at android.support.v4.widget.CursorFilter.publishResults(CursorFilter.java:68)
        at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我的建议方法:

  public synchronized Cursor getSuggestions(String[] selectionArgs) {
    String selection = FIELD_title + " like ? ";

    if (selectionArgs != null) {
        if (!selectionArgs[0].isEmpty()) {
            selectionArgs[0].replaceAll("'", "");
            selectionArgs[0] = "%" + selectionArgs[0] + "%";
        } else {
            selection = null;
            selectionArgs = null;
        }
    }

    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setProjectionMap(mAliasMap);
    queryBuilder.setTables(TABLE2_NAME);
    SQLiteDatabase db = mSearchDBOpenHelper.getReadableDatabase();
    Cursor c = null;
    if (db.isOpen()) {
        c = queryBuilder.query(db,
                new String[]{"_ID",
                        SearchManager.SUGGEST_COLUMN_TEXT_1,
                        SearchManager.SUGGEST_COLUMN_TEXT_2,
                        SearchManager.SUGGEST_COLUMN_ICON_1,
                        SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID},
                selection,
                selectionArgs,
                null,
                null,
                FIELD_title + " asc ", "10"
        );
    }
    return c;
}

现在我想说明我的数据库只被实例化一次,我没有泄漏它,我只有一个活动.我注意到的是,当出现竞争条件时,更有可能发生此错误.我的onQueryTextChange监听器:

public boolean onQueryTextChange(String newText) {
            query = newText;
            query = query.replaceAll("[\\s%\"^#<>{}\\\\|`]", "%20");

            if (query.length() > 1) {
            // same problem here
               fireOtherMethod();
            } else {
                    String[] selArgs = {query};
                    searchDB.cleanAutoCompleteRecords();
                    Log.e("c.isClosed()", String.valueOf(searchDB.getSuggestions(selArgs).isClosed()));
                     searchAdapter.changeCursor(searchDB.getSuggestions(selArgs));
            }

            return true;
        }

日志报告光标始终打开,我的数据库也是.我尝试更改光标时发生错误:

searchAdapter.changeCursor(searchDB.getSuggestions(selArgs));

所以,如果我只是开火:

searchDB.getSuggestions(selArgs)

没有问题,没有崩溃.

我无法抓住这个错误.我不知道我做错了什么.任何帮助将不胜感激!

更新:
我试过这样做:

Cursor c = searchDB.getSuggestions(selArgs); 
Cursor oldC = searchAdapter.getCursor(); 
if (oldC != null && !oldC.isClosed()) 
  oldC.close(); 
if (!c.isClosed()) 
  searchAdapter.changeCursor(c); 
else searchAdapter.changeCursor(null);

但结果是一样的.

解决方法:

当您调用changeCursor时,您将关闭现有游标.

public void changeCursor (Cursor cursor)

Added in API level 1 Change the underlying cursor to a new cursor. If
there is an existing cursor it will be closed.

您可以尝试关闭当前游标,然后创建新游标,而不是在尚未创建新游标时将其传递给changeCursor(新游标).

总是很好检查当前光标是否存在或关闭,如果在尝试这些时出现这些错误.

https://developer.android.com/reference/android/widget/CursorAdapter.html

本文标题为:java.lang.IllegalStateException:尝试重新打开已经关闭的对象:SQLiteQuery

基础教程推荐