База данных не закрыта - PullRequest
       2

База данных не закрыта

1 голос
/ 25 января 2012

Я посмотрел на другие вопросы, касающиеся этой проблемы, и попробовал их решения, но, к сожалению, это не помогло мне.

Проблема не имеет критического характера, то есть моя программа не падает, она продолжает работать, ноВ любом случае, я бы не хотел, чтобы при наличии ошибок.

Я использую класс AsyncTask для создания некоторых объектов и загрузки их в массив.База данных, которую я использую - это файл, полученный из сети, поэтому у меня нет класса DBhelper.Я открываю БД внутри doInBackround AsyncTask.Внутри него у меня есть try-catch, где я делаю всю свою работу с БД.

Сначала у меня были переменные для db и курсоров внутри оператора try, а такжеВ конце у меня было закрытие db и курсоров .Я нашел одну ссылку, в которой говорилось, что следует использовать try-catch-final, поэтому я сделал это, переместив объявление переменной вне оператора try-catch-final и управляя закрытием db и cursor переменные в final части, но все равно это не помогает, ошибки все еще здесь.

Вот некоторые ошибки, я не буду все C / P:

01-25 17: 22: 45.142: E / Database (333): close () никогда не вызывался явно для базы данных '/data/data/stet.cityapp/app_databases/baza.db

01-25 17: 22: 45.142: E / Database (333): android.database.sqlite.DatabaseObjectNotClosedException: приложение не закрывало курсор или объект базы данных, который был открыт здесь

01-25 17:22: 45.142: E / База данных (333): в stetocina.cityapp.SplashScreen $ LoadDB.doInBackground (SplashScreen.java:1)

01-25 17: 22: 45.142: E / База данных (333): вjava.util.concurrent.FutureTask $ Sync.innerRun (FutureTask.java:306)

01-25 17: 22: 45.142: E / База данных (333): на java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:581)

Структура кода:

protected Boolean doInBackground(String... params) {
SQLiteDatabase db = null;
Cursor poisCursor = null, tmpCursor = null;
String whereString;
try {               
    String DBpath = getDir("databases", 0).getAbsolutePath() + File.separator + "baza.db";
    if (SQLiteDatabase.openDatabase(DBpath, null, SQLiteDatabase.OPEN_READONLY) == null) return false;
    db =  SQLiteDatabase.openDatabase(DBpath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);

    ...

    result = true;
} catch (Exception e) {
    result = false;
    return result;
} finally {
    if (!poisCursor.isClosed() || poisCursor != null) {
        poisCursor.deactivate();
        poisCursor.close();
        poisCursor = null;
    }
    if (!db.isOpen() || db != null) {
        db.close();
        db = null;
    }
}
return result;

}

Может быть какая-то проблема, котораяЯ делаю это в AsyncTask?В методу onPostExecute AsyncTaks, если все прошло хорошо и результат верен, я открываю новую активность, и во время отладки я заметил, что ошибка отображается только при отображении новой активности, а не сразу после выхода изdoInBackground.

Спасибо за помощь!

Ответы [ 2 ]

3 голосов
/ 25 января 2012

Разве база данных не открывается дважды?

  1. внутри условия if (if (SQLiteDatabase.openDatabase (DBpath, null, SQLiteDatabase.OPEN_READONLY) == null) возвращает false;)

  2. в следующей строке (db = SQLiteDatabase.openDatabase (DBpath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);)

и вы закрываете только второй (дБ).

1 голос
/ 25 января 2012

Присмотритесь :) Это

if (!db.isOpen() || db != null) {
    db.close();
    db = null;
}

будет пытаться закрыть базу данных, только если она не открыта . Кроме того, я думаю, что что-то не так с

|| x != null

часть обоих пунктов.

В Java "двойные" логические операторы условны . Для || это означает, что если первый аргумент true , то второй аргумент не будет оцениваться вообще, поскольку логическое ИЛИ уже будет истинным, несмотря ни на что. Если это не так - тогда ваша ссылка проверяется на ноль. Итак, что вы делаете, вы проверяете, закрыт ли курсор. И если закрыто , вы проверяете ссылку на нулевое значение - что, очевидно, будет истинным, если вы успешно вызвали любой метод для него, поэтому вторая проверка не используется.

Я думаю, что правильные пункты будут

if ( poisCursor != null && !poisCursor.isClosed()) // prevent NPE when calling .isClosed() in case poisCursor is null

и

if (db != null && db.isOpen()) // same thing + note the absence of negation

(Подробнее об условных операторах можно прочитать здесь: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html)

Редактировать: @ firebolt7 прав, вы теряете ссылку на объект, который получаете при вызове open () в предложении if.

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