irobotxx
irobotxx

Reputation: 6063

Cursor and Database doesn't get closed android

Good day, i have this problem with my sqlite database on a widget application, it never gets closed even when i explicitly call it. i get this logcat error

02-26 00:49:42.070: E/Database(18049): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

and for some reason, when i get a cursor and call the getCount() method, it always increments with the last value also added. for example.. if i get cursor and the getCount() method returns a value of 5 from a column and i later remove the widget. when i add the widget again and query a different column which i know has a value of 6, i instead get 11 as the return value from the cursor. getCount() method. its like the cursor and the database never closes. any ideas what could be wrong?..

method:

private void setTag(String tag){
WeatherImageDB weatherimagedb = new WeatherImageDB(this); // get logcat error on this line
        weatherimagedb.open();

        ArrayList<String> image_list = new ArrayList<String>();
        image_list.clear();

            if(weatherimagedb.open() != null){
            Cursor cursor = weatherimagedb.retrieveTag(tag);
            Log.d(TAG, "size is " + cursor.getCount()); // this always gets incremented with also the last value added

             if(cursor.moveToFirst()){
                do{
                    image_list.add(cursor.getString(cursor.getColumnIndex(tag)));
                    //System.out.println("imagelisted!!");
                }       
                while(cursor.moveToNext());

                }

                //do other stuffs here with arraylist and then clear

            }
            image_list.clear();
            cursor.close();
            weatherimagedb.close();

        }

and code in database class:

    private final Context mcontext;
    private DBHelper dbhelper;
    private SQLiteDatabase db;

    public WeatherImageDB(Context context){
        mcontext = context;
        dbhelper = new DBHelper(mcontext);
    }

    public class DBHelper extends SQLiteOpenHelper {

        DBHelper(Context context){
            super(context, IMAGE_DB, null, DATABASE_VERSION);

        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS imagetags");
            onCreate(db);   
        }       
    }


    public WeatherImageDB open() throws SQLException {
        try{
            db = dbhelper.getWritableDatabase();
        }catch(SQLException e){
            db = dbhelper.getReadableDatabase();
        }
        return this;

    }

    public void close(){
        Log.d(TAG, "calling close on Database Object here");
        if(dbhelper != null){
        dbhelper.close();
        db.close();
        }
    }

    public long tagImage(String pathname, ContentValues val){   
        return db.insert(DATABASE_TABLE, null, val);    
    }

    public boolean deleteTag(String entry ){
        return db.delete(DATABASE_TABLE, null, null) >0;
    }

    public Cursor retrieveTag(String tag){
        //open();
        String[] condition = {tag};
        Cursor cursor = db.query(DATABASE_TABLE, condition, null, null, null, null, null);      
        return cursor;
    }

}

Upvotes: 0

Views: 239

Answers (1)

Sai Mukesh
Sai Mukesh

Reputation: 411

The scope of the cursor that you declared will be inside if loop only....I think there might be some other global object with same name as "cursor"...

if(weatherimagedb.open() != null){
    Cursor cursor = weatherimagedb.retrieveTag(tag);
    //some stuff--> make sure there are no return statements in this part.
      //If any return statement  exists close   the cursor and then execute return

    //it should be closed here
    cursor.close(); 
}
//You are closing outside if loop which is holding reference of some other cursor
cursor.close(); 

Upvotes: 1

Related Questions