user590849
user590849

Reputation: 11785

why is my application throwing finalizer exception in android?

i have an application in which there is constantly this exception being thrown...

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)

i don't understand why this is happening. i have closed all my cursors, and also i have closed the cursors before the databases... ie c.close() comes before db.close()

what could be the problem?

thank you in advance.

EDIT: i think this class is causing the exception because it is the only one dealing with databases

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; 
    }
    }
}

Upvotes: 1

Views: 1855

Answers (2)

WarrenFaith
WarrenFaith

Reputation: 57702

An addition to CommonsWare:

In your checkEventInDatabase() you reassign the c variable, if the c.getCount() is not 0, so there you create an cursor which you never close.

And please: Every time you call getCount() or getColumnCount() in a loop, god kills a kitten! (see getData())

Upvotes: 2

CommonsWare
CommonsWare

Reputation: 1007584

You are missing an else towards the end of checkIfThereIsEvent().

If that does not clear it up, simply log each Cursor you open yourself via a call to Log, and then compare the log entries to figure out which Cursor is the one being leaked.

Also:

  • Never hardwire paths. Get rid of /data/data/com.helios.NauticDates. Either use SQLiteOpenHelper or use getDatabasePath().
  • There is no value in continuously opening and closing your database this way. Please consider using SQLiteOpenHelper, putting these methods on that class, and keeping your SQLiteOpenHelper around longer (e.g., lifetime of your activity or service, or a singleton for your whole app)

Upvotes: 2

Related Questions