【问题标题】:Finalizing a Cursor that has not been deactivated or closed Error in Content provider's query class完成尚未停用或关闭的游标内容提供者的查询类中的错误
【发布时间】:2013-05-27 22:59:54
【问题描述】:

有关此特定错误消息的类似问题已在 Stack Overflow 中多次提出。我找不到与我的情况相匹配的。就这样吧。

当我打开严格模式时,我在内容提供程序的 query 方法中收到此错误。我的内容提供者的查询方法在下面调用queryDirections(...)。我只是调用db.query 方法并返回光标。如何关闭此光标?编译器在该游标未关闭下面的行返回语句中抱怨。详细的错误信息如下。 谢谢。

内容提供者

    private Cursor queryDirections(Uri uri, String[] columns, 
        String selection, String[] selectionArguments,
        String sortOrder) {
            SQLiteDatabase db = mySqliteOpenHelper.getReadableDatabase();
            return db.query(C.Db.TABLE_DIRECTIONS, columns, 
                     selection, selectionArguments, null, null, sortOrder);
    }

从活动中调用

continued...
case R.id.spinnerStops:
    AsyncQueryHandler handler = new AsyncQueryHandler(getContentResolver()) {
        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor stopCursor) {
            stopCursor.moveToFirst();
            int columnIndex = stopCursor.getColumnIndex(Stop.KEY_TAG);
            if (stopCursor.getCount() > 0) {
                mStopTag = stopCursor.getString(columnIndex);
                stopCursor.close();
            }
        };
    };
    handler.startQuery(1, null, C.ContentUri.STOP, 
                           new String[] { 
                               C.Db.TABLE_STOPS + "." + Stop.KEY_TITLE,
                               C.Db.TABLE_STOPS + "." + Stop.KEY_TAG }, 
                       "Stops._id=" + id, null, null);
    break;

我还为我的两个微调器适配器覆盖了 onStop

@Override
protected void onStop() {
    MyLogger.log("closing cursor");
    try {
        if (mStopsAdapter != null) {

            mStopsAdapter.getCursor().close();
            mStopsAdapter = null;
        }
        if (mDirectionAdapter != null) {
            mDirectionAdapter.getCursor().close();
            mDirectionAdapter = null;
        }
    } catch (Exception e) {
    }
    super.onStop();

}

错误消息

05-31 23:30:23.295: E/StrictMode(28918): Finalizing a Cursor that has not been deactivated or closed. database = /data/data/com.thuptencho.torontotransitbus/databases/appdb.db, table = directions, query = SELECT tag FROM directions WHERE _id=-999
05-31 23:30:23.295: E/StrictMode(28918): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
05-31 23:30:23.295: E/StrictMode(28918):    at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:98)
05-31 23:30:23.295: E/StrictMode(28918):    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:50)
05-31 23:30:23.295: E/StrictMode(28918):    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
05-31 23:30:23.295: E/StrictMode(28918):    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
05-31 23:30:23.295: E/StrictMode(28918):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
05-31 23:30:23.295: E/StrictMode(28918):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
05-31 23:30:23.295: E/StrictMode(28918):    at com.thuptencho.torontotransitbus.provider.TheContentProvider.queryDirections(TheContentProvider.java:169)
05-31 23:30:23.295: E/StrictMode(28918):    at com.thuptencho.torontotransitbus.provider.TheContentProvider.query(TheContentProvider.java:109)
05-31 23:30:23.295: E/StrictMode(28918):    at android.content.ContentProvider.query(ContentProvider.java:652)
05-31 23:30:23.295: E/StrictMode(28918):    at android.content.ContentProvider$Transport.query(ContentProvider.java:189)
05-31 23:30:23.295: E/StrictMode(28918):    at android.content.ContentResolver.query(ContentResolver.java:372)
05-31 23:30:23.295: E/StrictMode(28918):    at android.content.ContentResolver.query(ContentResolver.java:315)
05-31 23:30:23.295: E/StrictMode(28918):    at android.content.AsyncQueryHandler$WorkerHandler.handleMessage(AsyncQueryHandler.java:79)
05-31 23:30:23.295: E/StrictMode(28918):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-31 23:30:23.295: E/StrictMode(28918):    at android.os.Looper.loop(Looper.java:137)
05-31 23:30:23.295: E/StrictMode(28918):    at android.os.HandlerThread.run(HandlerThread.java:60)

【问题讨论】:

  • 如果您想在使用 Cursor 的位置发布您的代码,这可能有助于确定应在何处添加 cursor.close() 类型的调用。
  • 我已编辑添加与ContentResolver 通话相关的代码。

标签: android android-contentprovider android-cursor


【解决方案1】:

Cursors 从ContentProvider 返回必须由接收组件(ActivityService 等)而不是由ContentProvider 本身关闭。

【讨论】:

  • 您如何在搜索建议的上下文中做到这一点?
  • @axd - 假设你的意思是custom search suggestions,它应该照顾自己的光标。
  • 这正是我的问题...框架没有关闭光标,我通过 Strict 发现了。
  • @axd - 通过查看source code for SearchView,它确实关闭了光标(这就是changeCursor() 所做的),但它在onDetachedFromWindow() 中异步执行,这可能显示为StrictMode 中的误报。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 2012-01-30
  • 2012-04-12
  • 2011-03-05
  • 1970-01-01
相关资源
最近更新 更多