Nano Hash - криптовалюты, майнинг, программирование

Как безопасно закрыть курсор и базу данных?

Я извлек записи из базы данных с помощью курсора. Это работает идеально. Но у меня есть некоторые ошибки в 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;
}

Мой логарифм -

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.

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

16.12.2011

Ответы:


1

EDIT: Если вы возвращаете уже закрытый курсор, вы не можете его использовать. Откройте базу данных перед вызовом метода, затем закройте курсор, а затем базу данных после вызова метода.

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

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();
16.12.2011
  • Это решение работает для меня. Спасибо, @Noureddine :-) 16.05.2018

  • 2

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

    @Override
    public boolean onCreate() {
        mOpenHelper = getDBOpenHelper(); 
        return true;
    }
    @Override
    public void shutdown() {
    mOpenHelper.close();
        super.shutdown();
    }
    
    22.10.2012

    3

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

    16.12.2011

    4

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

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

    16.12.2011

    5

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

        if (dbCursor != null && dbCursor.moveToFirst()) {
                try {
                                  //do stuff
                }  catch (exceptions) {
                                  //catch possible exceptions
                } finally {
    
                    if (dbCursor != null && !dbCursor.isClosed()) {
                        dbCursor.close();
                    }
                }
    
    16.12.2011
  • Это закрывает курсор, а не базу данных. 16.12.2011
  • да - вы читали последнюю часть вопроса? Чтобы процитировать: Итак, кто-нибудь скажет мне, как мне получить безопасное закрытие для курсора и базы данных после извлечения записей. 16.12.2011

  • 6

    Попробуйте передать 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;
        }
    
    04.07.2016
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..