почему мое приложение выбрасывает исключение финализатора в Android? - PullRequest
1 голос
/ 25 апреля 2011

У меня есть приложение, в которое постоянно выдается это исключение ...

04-25 18:47:38.024: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.035: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44dd1e68 on null that has not been deactivated or closed
04-25 18:47:38.035: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.035: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.044: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.064: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e4c048 on null that has not been deactivated or closed
04-25 18:47:38.064: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.064: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.074: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.094: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e35310 on null that has not been deactivated or closed
04-25 18:47:38.094: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.094: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.104: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.104: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e7f738 on null that has not been deactivated or closed
04-25 18:47:38.104: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.104: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.114: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.136: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e04a90 on null that has not been deactivated or closed
04-25 18:47:38.136: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.136: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.155: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.155: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e944f0 on null that has not been deactivated or closed
04-25 18:47:38.155: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.155: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.164: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.184: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e90548 on null that has not been deactivated or closed
04-25 18:47:38.184: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.184: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.194: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.194: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e6b0c8 on null that has not been deactivated or closed
04-25 18:47:38.194: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.194: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)
04-25 18:47:38.204: INFO/dalvikvm(10290): Uncaught exception thrown by finalizer (will be discarded):
04-25 18:47:38.225: INFO/dalvikvm(10290): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44e4af40 on null that has not been deactivated or closed
04-25 18:47:38.237: INFO/dalvikvm(10290):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-25 18:47:38.245: INFO/dalvikvm(10290):     at dalvik.system.NativeStart.run(Native Method)

Я не понимаю, почему это происходит.я закрыл все свои курсоры, а также я закрыл курсоры до того, как базы данных ... т.е. c.close() предшествует db.close()

в чем может быть проблема?

спасибо вadvance.

EDIT: я думаю, что этот класс вызывает исключение, потому что он единственный, имеющий дело с базами данных

package com.helios.NauticDates;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class HandleDatabase {

    public void executeSql(String query) {
        SQLiteDatabase db = SQLiteDatabase.openDatabase(
                "/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
                null, SQLiteDatabase.OPEN_READWRITE);
        db.execSQL(query);
        db.close();
    }

    public boolean checkCategory(String name) {
        // TODO Auto-generated method stub
        SQLiteDatabase db = SQLiteDatabase.openDatabase(
                "/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
                null, SQLiteDatabase.OPEN_READWRITE);
        String query = "select * from EventCategories where categoryname ='"
                + name + "'";
        Cursor c = db.rawQuery(query, null);
        if (c.getCount() == 0) {
            c.close();
            db.close();
            return true;
        } else {
            c.close();
            db.close();
            return false;
        }
    }

    public String[][] getData(String[] columnnames, String tablename) {
        SQLiteDatabase db = SQLiteDatabase.openDatabase(
                "/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
                null, SQLiteDatabase.OPEN_READWRITE);
        String query = "select ";
        for (int i = 0; i < columnnames.length; i++) {
            if (i == columnnames.length - 1)
                query += columnnames[i] + " ";
            else
                query += columnnames[i] + ",";
        }
        query += "from " + tablename + " where eventid=128";
        Cursor c = db.rawQuery(query, null);
        String[][] result = new String[c.getColumnCount()][c.getCount()];
        for (int i = 0; i < c.getColumnCount(); i++) {
            c.moveToFirst();
            for (int j = 0; j < c.getCount(); j++) {
                result[i][j] = c.getString(c.getColumnIndex(columnnames[i]));
                Log.i("getdata", result[i][j]);
                c.moveToNext();
            }
        }
        c.close();
        db.close();
        return result;
    }

    public boolean checkIfThereIsEvent(String cdate, Date currentdate) {
        Date enddate = (Date) currentdate.clone();
        enddate.setHours(0);
        enddate.setMinutes(0);
        enddate.setSeconds(0);
        String edate = (String) android.text.format.DateFormat.format(
                "yyyy-MM-dd", enddate);

        Log.i("handledatabase", cdate + "-" + edate);
        SQLiteDatabase db = SQLiteDatabase.openDatabase(
                "/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
                null, SQLiteDatabase.OPEN_READWRITE);
        String query = "SELECT datetime(startdat, 'unixepoch') AS std, datetime(enddat, 'unixepoch') AS end FROM EventDetails WHERE ((std <= '"
                + cdate
                + "' AND end >= '"
                + cdate
                + "' )||( date(enddat,'unixepoch') = '1970-01-01' AND date(startdat,'unixepoch') = '"
                + edate + "')) LIMIT 1";
        Log.i("thequery", query);
        Cursor c = db.rawQuery(query, null);
        if (c.getCount() > 0) {
            c.close();
            db.close();
            return true;
        }
        {
            c.close();
            db.close();
            return false;
        }
    }

    public boolean checkEventInDatabase(String dateofchange, String eventid) {
        SQLiteDatabase db = SQLiteDatabase.openDatabase(
                "/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
                null, SQLiteDatabase.OPEN_READWRITE);
        String query = "select * from EventDetails where eventid='"+eventid+"' limit 1";
        Cursor c = db.rawQuery(query, null);
        if(c.getCount()==0){
            c.close();
            db.close();
            return false;
        }
        else{
            query = "select * from EventDetails where eventid='"+eventid+"'and changed='"+dateofchange+"' limit 1";
            c= db.rawQuery(query, null);
            if(c.getCount()>0){
                c.close();
                db.close();
                return true;
            }
            else{
                c.close();
                db.close();
                return true;
            }
    }
}

    public boolean checkIfEventChanged(String dateofchange, String eventid) {
        SQLiteDatabase db = SQLiteDatabase.openDatabase(
                "/data/data/com.helios.NauticDates/CalendarEvent.sqlitedb",
                null, SQLiteDatabase.OPEN_READWRITE);
        String query = "select * from EventDetails where eventid='"+eventid+"'and changed='"+dateofchange+"' limit 1";
        Cursor c= db.rawQuery(query, null);
        if(c.getCount()>0){
            c.close();
            db.close();
            return false;
        }
        else{
            c.close();
            db.close();
            return true; 
    }
    }
}

Ответы [ 2 ]

2 голосов
/ 25 апреля 2011

Дополнение к CommonsWare:

В вашем checkEventInDatabase() вы переназначаете переменную c, если c.getCount() не равно 0, поэтому вы создаете курсор, который вы никогда не закрываете.

И, пожалуйста: Каждый раз, когда вы звоните getCount() или getColumnCount() в цикле, бог убивает котенка! (см. getData())

2 голосов
/ 25 апреля 2011

Вы пропускаете else в конце checkIfThereIsEvent().

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

Также:

  • Никогда не проводные пути.Избавиться от /data/data/com.helios.NauticDates.Либо используйте SQLiteOpenHelper, либо используйте getDatabasePath().
  • Нет смысла непрерывно открывать и закрывать вашу базу данных таким образом.Пожалуйста, рассмотрите возможность использования SQLiteOpenHelper, поместите эти методы в этот класс и сохраняйте ваш SQLiteOpenHelper дольше (например, время жизни вашей деятельности или услуги или единичное целое для всего приложения)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...