2

i saw many posts here about it but i just cant get my app to stop sent me errors about me not closing DB . my DB is acces sometimes by the activity and sometimes from background class(service) .

i added to the activity's using DB

protected void onDestroy() {
    Log.d("OnDestroy", "called");
    sqlAdapter helper = new sqlAdapter(StartScreen.this);
    helper.close();
    super.onDestroy();
}

as suggested here in many post but it wont solve the problem .

any ideas or explain to help me understand ? the app not crash or anything but a lot of error about me not closing the DB

thanks!

Jesus Dimrix
  • 4,378
  • 4
  • 28
  • 62

2 Answers2

0

You should close it every time you are done. If you create a cursor to access it then after you get the data and save it or finish your processing on it then you should close the cursor. Then you open it again the next time you need it. This answer should help you

Community
  • 1
  • 1
codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • I just want to point out this is not necessarily true in cases where you are using connection pools. I don't think this is the case in this situation, but closing your connections when using a connection pool defeats the purpose of using a connection pool. – CodeChimp Mar 29 '13 at 14:14
0

In your example, it appears that you are creating a new object in onDestroy and not closing old ones. So every time you do

sqlAdapter helper = new sqlAdapter(StartScreen.this);

You are creating a new object and you'll have a ton of unclosed references and this is what is causing the warnings.

Instead, it looks like you may looking for a singleton design pattern which will allow you to maintain one object in your application and then close it in onDestroy.

public void onDestroy() {
    super.onDestroy();
    // close database
    final MySqlHelper helper = MySqlHelper.getInstance();
    helper.getDatabase().close();
}

Otherwise it remains open until onDestroy just like you're trying to do now. This of course should be used if appropriate and you're actively using it in your application. If you rarely use the database, you will be fine just closing it after each use.

The idea is that you're reducing database open / close calls if you do a moderate amount of them and will be more efficient in that use case.

Here is a very, very stripped down example of a singleton.

public class MySqlHelper extends SQLiteOpenHelper {
    static MySqlHelper mInstance = null;
    static SQLiteDatabase mDatabase = null;

    public static MySqlHelper getInstance() {
        if (mInstance == null) {
            // call private constructor
            mInstance = new MySqlHelper();
        }
        mDatabase = mInstance.getWritableDatabase();
        while(mDatabase.isDbLockedByCurrentThread() || mDatabase.isDbLockedByOtherThreads()) {
            // loop until available
        }
        return mInstance;
    }

    private MySqlHelper() {
        // mContext here is just a placeholder for your ApplicationContext
        // that you should have available to this class.
        super(mContext, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // all other filled out methods like onCreate, onUpgrade, etc
}

Now you can use this to implement your datasource

public class MyDataSource {
    // Database fields
    private final SQLiteDatabase mDatabase;
    private final MySqlHelper mHelper;

    public MyDataSource() {
        mHelper = MySqlHelper.getInstance();
        mDatabase = mHelper.getDatabase();
    }

    // add your custom methods 

    private int update(ContentValues values, String whereClause) {
        int rowsUpdated = 0;
        synchronized (mDatabase) {
            rowsUpdated = mDatabase.update(MySqlHelper.TABLE_NAME, values, whereClause, null);
        }
        return rowsUpdated;
    }

    public int updateById(ContentValues values, int id) {
        final String whereClause = MySqlHelper.COLUMN_ID + "=" + id;
        return this.update(values, whereClause);
    }
}
Kirk
  • 16,182
  • 20
  • 80
  • 112