Как безопасно закрыть курсор и базу данных? - PullRequest
9 голосов
/ 16 декабря 2011

Я получил записи из базы данных с помощью курсора. Это идеальная работа. Но у меня есть некоторые ошибки в Logcat, когда я использую этот код

public Cursor fetchAll()
{
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior); 
    return cursor;
}

Мой logcat - -

12-16 14:49:20.774: E/Database(18611): close() was never explicitly called on database '/data/data/com.android.application/databases/appZ.db' 
12-16 14:49:20.774: E/Database(18611): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
12-16 14:49:20.774: E/Database(18611):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
12-16 14:49:20.774: E/Database(18611):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.DBHelper.fetchAll(DBHelper.java:91)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.ApplicationActivity.sc_adapter(ApplicationActivity.java:1210)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.ApplicationActivity.refresh_data(ApplicationActivity.java:1195)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.ApplicationActivity.onKeyDown(ApplicationActivity.java:1440)
12-16 14:49:20.774: E/Database(18611):  at android.view.KeyEvent.dispatch(KeyEvent.java:1037)
12-16 14:49:20.774: E/Database(18611):  at android.app.Activity.dispatchKeyEvent(Activity.java:2068)
12-16 14:49:20.774: E/Database(18611):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
12-16 14:49:20.774: E/Database(18611):  at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
12-16 14:49:20.774: E/Database(18611):  at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
12-16 14:49:20.774: E/Database(18611):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
12-16 14:49:20.774: E/Database(18611):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-16 14:49:20.774: E/Database(18611):  at android.os.Looper.loop(Looper.java:123)
12-16 14:49:20.774: E/Database(18611):  at android.app.ActivityThread.main(ActivityThread.java:4627)
12-16 14:49:20.774: E/Database(18611):  at java.lang.reflect.Method.invokeNative(Native Method)
12-16 14:49:20.774: E/Database(18611):  at java.lang.reflect.Method.invoke(Method.java:521)
12-16 14:49:20.774: E/Database(18611):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-16 14:49:20.774: E/Database(18611):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-16 14:49:20.774: E/Database(18611):  at dalvik.system.NativeStart.main(Native Method)

Я ссылался на что-то из здесь . Они сказали, что используют getReadableDatabase (). Я также использую этот метод. И я также использую этот метод,

public Cursor fetchAll()
{
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior); 
   if (cursor!=null)
    {
        cursor.close();
    }
   if (db!=null)
    {
        db.close();
    }
    return cursor;
}

после этого с ошибкой вроде -

Database wasn't open.

После того, как у меня есть эти ошибки в моей базе данных. Итак, кто-нибудь скажет мне, как получить защитное закрытие для курсора и базы данных после получения записей.

Ответы [ 6 ]

10 голосов
/ 16 декабря 2011

РЕДАКТИРОВАТЬ: Если вы вернете курсор, который уже закрыт, вы не можете его использовать.Откройте базу данных перед вызовом метода, затем закройте курсор, а затем базу данных после вызова метода.

Вы можете закрыть курсор после того, как закончите с ним, вот так:

Cursor cursor = fetchAll();
... // Do your work with the cursor
cursor.close();

Или, если вы используете курсор из действия, и вам нужно запросить (когда действие перезапускается, останавливается ...), вы можете использовать это:

Cursor cursor = fetchAll();
startManagingCursor(cursor); // Android will take care of the cursor for you
// Do your work with the cursor

Чтобы закрыть базу данных (после закрытиякурсор, или если внутри действия в onDestroy() предпочтительно):

dbhelper.close();
3 голосов
/ 22 октября 2012

В вашем классе, который расширяет ContentProvider, если вы открываете соединение с базой данных и устанавливаете помощника в качестве переменной экземпляра в onCreate, вы можете закрыть соединение с базой данных при завершении работы.

@Override
public boolean onCreate() {
    mOpenHelper = getDBOpenHelper(); 
    return true;
}
@Override
public void shutdown() {
mOpenHelper.close();
    super.shutdown();
}
2 голосов
/ 16 декабря 2011

Лучше было бы открыть его в onResume () и закрыть в onPause ().

1 голос
/ 16 декабря 2011

каждый раз, когда вы вызываете этот метод, база данных будет открываться в режиме чтения, но вы не закрывали базу данных, поэтому получаете эту ошибку. открыть только один раз, как из метода onCreate (), и закрыть в destroy ()

пока вы можете закрыть курсор после извлечения строк, а когда курсор больше не нужен, закройте его и установите в ноль

1 голос
/ 16 декабря 2011

Вы также можете обратиться к этому ответу (предлагает, где следует закрывать соединения объектов курсора / БД в зависимости от состояния Activity) или к этому (предлагает, как закрыть объект SQLiteDatabase ). Не нужно уточнять, когда это уже написано один раз. Несмотря на это, ниже идея для части кодирования.

    if (dbCursor != null && dbCursor.moveToFirst()) {
            try {
                              //do stuff
            }  catch (exceptions) {
                              //catch possible exceptions
            } finally {

                if (dbCursor != null && !dbCursor.isClosed()) {
                    dbCursor.close();
                }
            }
0 голосов
/ 05 июля 2016

Попробуйте передать SQLiteDatabase в качестве параметра в метод fetchAll:

MyDatabase db = new MyDatabase(this);

....

Cursor myCursor = db.fetchAll(db.getReadableDatabase());

myCursor.close();
db.close();




    public Cursor fetchAll(SQLiteDatabase db, String listName) {
        String sql = "select ID _id, Name from ListName where Name = ? order by ID";
        Cursor c = db.rawQuery(sql, new String[] { listName });
        c.moveToFirst();

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