Как мне исправить «Пожалуйста, убедитесь, что вы явно вызываете close () для вашего курсора»? - PullRequest
0 голосов
/ 09 марта 2011

Я создаю приложение Android с действием, которое имеет следующий код:

public class SavedSalesActivity extends Activity {

    protected ListView mSalesList;
    protected Cursor mSalesCursor;
    protected SalesCursorAdapter mSalesAdapter;
    protected SalesDbAdapter mDb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sales_list);

        mDb = new SalesDbAdapter(this);
        mDb.open();
        mSalesCursor = mDb.getSaved();
        startManagingCursor(mSalesCursor);

        mSalesAdapter = new SalesCursorAdapter(this, R.layout.sales_list_item, mSalesCursor,
                new String[0], new int[0]);

        mSalesList = (ListView)findViewById(R.id.sales_listview);
        mSalesList.setAdapter(mSalesAdapter);
        mSalesList.setEmptyView(findViewById(android.R.id.empty));
        mSalesList.setOnItemClickListener(new OnItemClickListener() {...});
    }

    @Override
    protected void onStart() {
        Log.v(TAG, "Starting SavedSalesActivity");

        mDb.open();

        mSalesCursor = mDb.getSaved();
        startManagingCursor(mSalesCursor);

        super.onStart();
    }

    @Override
    protected void onStop() {
        Log.v(TAG, "Stopping SavedSalesActivity");

        mSalesCursor.close();

        mDb.close();

        super.onStop();
    }
}

Насколько я понимаю, этого должно быть более чем достаточно, чтобы правильно закрыть все мои ресурсы, однако, если я открою это действие и выйду из него кнопкой возврата устройства Android, я получу это в Logcat через короткий (переменный) период времени.

03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: SELECT * FROM sales ORDER BY featured DESC
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at com.maps.app.classifiedconcepts.sale.SalesDbAdapter.getSaved(SalesDbAdapter.java:149)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at com.maps.app.classifiedconcepts.sale.SavedSalesActivity.onCreate(SavedSalesActivity.java:113)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.os.Looper.loop(Looper.java:123)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at java.lang.reflect.Method.invokeNative(Native Method)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at java.lang.reflect.Method.invoke(Method.java:521)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):     at dalvik.system.NativeStart.main(Native Method)
03-08 19:33:58.503: ERROR/Database(5169): close() was never explicitly called on database '/data/data/com.maps.app.classifiedconcepts/databases/classified_concepts' 
03-08 19:33:58.503: ERROR/Database(5169): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
03-08 19:33:58.503: ERROR/Database(5169):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
03-08 19:33:58.503: ERROR/Database(5169):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
03-08 19:33:58.503: ERROR/Database(5169):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
03-08 19:33:58.503: ERROR/Database(5169):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
03-08 19:33:58.503: ERROR/Database(5169):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
03-08 19:33:58.503: ERROR/Database(5169):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
03-08 19:33:58.503: ERROR/Database(5169):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:112)
03-08 19:33:58.503: ERROR/Database(5169):     at com.maps.app.classifiedconcepts.sale.SalesDbAdapter.open(SalesDbAdapter.java:163)
03-08 19:33:58.503: ERROR/Database(5169):     at com.maps.app.classifiedconcepts.sale.SavedSalesActivity.onCreate(SavedSalesActivity.java:112)
03-08 19:33:58.503: ERROR/Database(5169):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-08 19:33:58.503: ERROR/Database(5169):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-08 19:33:58.503: ERROR/Database(5169):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-08 19:33:58.503: ERROR/Database(5169):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-08 19:33:58.503: ERROR/Database(5169):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-08 19:33:58.503: ERROR/Database(5169):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-08 19:33:58.503: ERROR/Database(5169):     at android.os.Looper.loop(Looper.java:123)
03-08 19:33:58.503: ERROR/Database(5169):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-08 19:33:58.503: ERROR/Database(5169):     at java.lang.reflect.Method.invokeNative(Native Method)
03-08 19:33:58.503: ERROR/Database(5169):     at java.lang.reflect.Method.invoke(Method.java:521)
03-08 19:33:58.503: ERROR/Database(5169):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-08 19:33:58.503: ERROR/Database(5169):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-08 19:33:58.503: ERROR/Database(5169):     at dalvik.system.NativeStart.main(Native Method)

Строка mSalesCursor = mDb.getSaved (); вызывает следующий код в моем SalesDbAdapter:

public Cursor getSaved() {
return mDb.query(TABLE_NAME, null, null, null, null, null, KEY_FEATURED + " DESC"); 
}

Что я делаю не так? Почему я получаю эти исключения? Я особенно озадачен, потому что я думал, что вызов startManagingCursor (mSalesCursor) сразу после инициализации mSalesCursor избавит меня от необходимости закрывать курсор в любом из методов жизненного цикла действия.

Ответы [ 3 ]

2 голосов
/ 20 января 2013

Для других людей, рассматривающих этот ответ, я всегда заключаю в себе использование курсора с помощью операторов try / catch / finally. Это обеспечивает уверенность в том, что курсор закрывается независимо от того, что происходит.

Я использую это так часто, что даже сделал шаблон Eclipse.

пример:

void foo() {
    Cursor c = null;
    try {
        c = db.get_somthing();
        do_something©;
    }       

    catch (Exception e) {
        print_err_msg(e);
    }

    finally {
        if (c != null) {
            c.close();
            c = null;
        }
    }
}
0 голосов
/ 09 марта 2011

Рассмотрим вызов startManagingCursor () .

0 голосов
/ 09 марта 2011

Вы должны переопределить onResume() и onPause() вместо onStart() и onStop() для подобных вещей. Ознакомьтесь с документацией Activity Lifecycle .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...