-1

I've this method to read the database:

class BDUtilities

    private Context context;
    private BDHelper bd;
    private SQLiteDatabase db_reader;
    private SQLiteDatabase db_writer;


    public BDUtilities(Context context){
        this.context = context;
        this.bd = new BDHelper(context);
        this.db_reader = bd.getReadableDatabase();
        this.db_writer = bd.getWritableDatabase();
    }

     public ArrayList<Boolean> getPreferences() {
        ArrayList<Boolean> resultados = new ArrayList<Boolean>();
        if (checkBeforeUse()) {
            try {
                int user_id = getUserId();

                Cursor c = db_reader.rawQuery("select cb_save_login, cb_save_pic_after_share," +
                        "cb_upload_anonym, cb_init_cat_pref, user_id from prefs where user_id = ?", new String[] { String.valueOf(user_id) });

                if (c.getCount() > 0){
                    c.moveToFirst();
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_save_login"))));
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_save_pic_after_share"))));
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_upload_anonym"))));
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_init_cat_pref"))));
                    c.close();
                } else { c.close(); }
            }
            finally {
                //both error
                //bd.close();
                //db_reader.close(); //error:
                //01-12 06:05:36.370: E/AndroidRuntime(1681): java.lang.IllegalStateException: 
                //attempt to re-open an already-closed object: SQLiteDatabase:                   
                //data/data/com.example.photopt/databases/projeto_ddm.db
            }
        }
        return resultados;
     }

I've tried to close db_reader that has bd_reader = database.getReadableDatabase(); but has error.

This code: This doesn't return error but after some uses it shows this:

01-12 05:51:29.647: W/SQLiteConnectionPool(1762): A SQLiteConnection object for database '/data/data/com.example.photopt/databases/projeto_ddm.db' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.

Severiano
  • 1,083
  • 3
  • 25
  • 54
  • What error does this throw: `db_reader.close()` ? – Simas Jan 12 '15 at 11:04
  • Possible duplicate of http://stackoverflow.com/questions/25307868/a-sqliteconnection-object-for-database-was-leaked-please-fix-your-application and http://stackoverflow.com/questions/19190218/android-sqliteconnection-object-for-database-was-leaked-even-closed – Piyush Jan 12 '15 at 11:10
  • i've seen that didn't worked, error is displayed above – Severiano Jan 12 '15 at 11:12
  • Do you close the `db_reader` only or `bd` too when "already closed" error is thrown? – Simas Jan 12 '15 at 11:12
  • You need to change this code if (c.getCount() > 0){ c.moveToFirst(); resultados.add(parse(c.getString(c.getColumnIndex("cb_save_login")))); resultados.add(parse(c.getString(c.getColumnIndex("cb_save_pic_after_share")))); resultados.add(parse(c.getString(c.getColumnIndex("cb_upload_anonym")))); resultados.add(parse(c.getString(c.getColumnIndex("cb_init_cat_pref")))); c.close(); } else { c.close(); } – Piyush Jan 12 '15 at 11:13
  • Close your cursor... cursor.close(); in your case. c.close(); – Dirk De Winnaar Jan 12 '15 at 11:20
  • @DirkDeWinnaar I close it, you can see it. – Severiano Jan 12 '15 at 11:21

3 Answers3

1

you are not closing db_writer

Regardless of not using it, you still open it at the intialisation.

    this.db_writer = bd.getWritableDatabase();

It is recommended to close it also, else the connection is leaked.

   this.db_writer.close();

Better yet would be to write a helper method that you can call:

public void CloseDb()
{
    if(db_writer.isOpen())
        db_writer.close();
    if(db_reader.isOpen())
        db_reader.close();

}

You can then call CloseDb() where appropriate (still need to close cursors as per normal). This method checks its open before closing, so does not try to close it twice.

You do not normally close a Databasehelper from within itself though. Usually once you have finished using it in an from an activity. (Call CloseDb() from your activity once you have finished, aka, onPause or onDestroy.)

IAmGroot
  • 13,760
  • 18
  • 84
  • 154
  • Could you please help to solve this [issue](https://stackoverflow.com/questions/62646206/unable-to-prevent-sqliteconnection-object-leakage) – MrinmoyMk Jun 29 '20 at 22:25
0

Try this....

if (c.getCount() > 0){
                    c.moveToFirst();
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_save_login"))));
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_save_pic_after_share"))));
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_upload_anonym"))));
                    resultados.add(parse(c.getString(c.getColumnIndex("cb_init_cat_pref"))));
                    c.close();
                    bd.close();
                } else {
                  c.close(); 
                  bd.close();
                }
Dirk De Winnaar
  • 167
  • 2
  • 9
0

this code stops the leak and fixes cursor problems.

public class DatabaseHelper extends SQLiteOpenHelper { 

  private static DatabaseHelper sInstance;

  private static final String DATABASE_NAME = "database_name";
  private static final String DATABASE_TABLE = "table_name";
  private static final int DATABASE_VERSION = 1;

  public static DatabaseHelper getInstance(Context context) {

    // Use the application context, which will ensure that you 
    // don't accidentally leak an Activity's context.
    if (sInstance == null) {
      sInstance = new DatabaseHelper(context.getApplicationContext());
    }
    return sInstance;
  }

  /**
   * Constructor should be private to prevent direct instantiation.
   * make call to static factory method "getInstance()" instead.
   */
  private DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }
}
Basheer Adel
  • 41
  • 1
  • 5