Android database connection and cursor Oh, my
When using Android, I have read a lot of blogs and tutorials on how to create and use database connections. Although I have many working examples, different implementations will lead to different problems
For example, I use the data source class, data source and database assistant class dbmanage
data source
public class DataSource {
// Database fields
private sqliteDatabase database;
private DBManagement dbHelper;
public SMSDataSource(Context context) {
dbHelper = new DBManagement(context);
}
public void open() throws sqlException {
if(database == null){
database = dbHelper.getWritableDatabase();
}
}
public Cursor exampleCursor(long constraint){
Cursor cur = database.query(DBManagement.TABLE_NAME,
new String[] {DBManagement.Column}, "constraint="+constraint, null, null, null, null);
return cur;
}
//.. other methods down here which do rawQuery, QueryBuilder, etc..
DBManagement
public class DBManagement extends sqliteOpenHelper{
// .. table deFinitions and columns etc ..//
public DBManagement(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
In the oncreate method in the activity, I will call datasource. Open() and the SQL connection has been opened. Then I will do the following:
DataSource datasource = new DataSource();
Cursor cursor = datasource.exampleCursor(1);
startManagingCursor(cursor);
If I navigate to a new activity, I receive the following error:
06-27 21:59:14.812: E/Database(13396): close() was never explicitly called on database '/data/data/com.example.package/databases/db.db'
If I add datasource. Close(); At the end of oncreate, no simple cursor adapter works, or if I perform an operation on the conextual menu, I get an error that DB is not opened
What is the best way to deal with the above problems?
So I did the following, and I still encountered database problems:
@Override
public void onBackPressed() {
// do something on back.
//Log.i(getClass().toString(), "onBackPressed");
datasource.close();
finish();
return;
}
@Override
protected void onResume(){
super.onResume();
onCreate(null);
}
@Override
protected void onRestart(){
datasource = new DataSource(this);
datasource.open();
filters = datasource.getFilterCursor();
startManagingCursor(filters);
super.onRestart();
}
@Override
protected void onPause(){
//Log.i(getClass().toString(), "onPause");
((CursorAdapter) adapter).getCursor().close();
datasource.close();
super.onPause();
}
@Override
protected void onStop(){
//Log.i(getClass().toString(), "onStop");
datasource.close();
super.onStop();
}
My datasource.java class has the following contents:
public Datasource(Context context){
dbHelper = new DBManagement(context);
}
public void open() throws sqlException {
if( database == null ){
database = dbHelper.getWritableDatabase();
}
}
public void close(){
if(dbHelper != null){
dbHelper.close();
}
}
resolvent:
This is actually very simple:
>After completion, explicitly close all cursors (last used), etc. > do not use startmanagingcursor() > make your database wrapper / Assistant / Manager / no matter what kind of detail > do not explicitly call close() on the database assistant. When your process terminates, I will close automatically
In addition: frequent opening and closing is definitely a bad idea because it brings a lot of overhead
Using a loader is also an option. You absolutely don't need to use a content provider to use a loader, but it's not that simple. Using a content provider involves IPC. If you don't intend to export data to other applications, there will usually be excessive killing