I use a database with multiple tables in my application. I have an XML parser which needs to write data to two tables while parsing. I created two database adapters for both tab
phoxicle's solution is a great starting point, but per Kevin Galligan's notes on Android's SQLite serialization, this implementation isn't thread safe and will fail silently when multiple database connections (e.g. from different threads) try to write the database:
If you try to write to the database from actual distinct connections at the same time, one will fail. It will not wait till the first is done and then write. It will simply not write your change. Worse, if you don’t call the right version of insert/update on the SQLiteDatabase, you won’t get an exception. You’ll just get a message in your LogCat, and that will be it.
So, multiple threads? Use one helper.
Here's a modified implementation of phoxicle's database adapter that uses a static SQLiteOpenHelper instance and is thus limited to a single database connection:
public class DBBaseAdapter {
private static final String TAG = "DBBaseAdapter";
protected static final String DATABASE_NAME = "db.sqlite";
protected static final int DATABASE_VERSION = 1;
protected Context mContext;
protected static DatabaseHelper mDbHelper;
private static final String TABLE_CREATE_FOO =
"create table foo (_id integer primary key autoincrement, " +
"bar text not null)");
public DBBaseAdapter(Context context) {
mContext = context.getApplicationContext();
}
public SQLiteDatabase openDb() {
if (mDbHelper == null) {
mDbHelper = new DatabaseHelper(mContext);
}
return mDbHelper.getWritableDatabase();
}
public void closeDb() {
mDbHelper.close();
}
protected static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE_CREATE_FOO);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " +
newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS routes");
onCreate(db);
}
}
}
Extend DBBaseAdapter for each table to implement your CRUD methods:
public class DBFooTable extends DBBaseAdapter {
public DBFooTable(Context context) {
super(context);
}
public void getBar() {
SQLiteDatabase db = openDb();
// ...
closeDb();
}