HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Android SQLite Database management

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
databasemanagementsqliteandroid

Problem

I'd like some opinions about my approach at using SQLite databases in android. Everything seems to work very well, but there may be something wrong that I hadn't noticed.

I don't like working with create/alter table statements in code, so I prefer creating my database with some SQLite client out there and putting it in assets folder. I use some logic to decide when the database must be replaced and which records need to be kept, then use this code in a class called DbManager:

```
private static SQLiteDatabase _db = null;

public static Object lock = new Object();

private static SQLiteDatabase getDB() {
if (_db == null) {
_db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE);
}

return _db;
}

//this is the approach used for insert operations, but is the same for update, delete etc
public static boolean insert(String tableName, ContentValues values) {
try {
return getDB().insert(tableName, null, values) >= 0;
} catch (Exception e) {
LogHelper.WriteLogError("error in DB_manager.insert function", e);
return false;
}
}

public static synchronized void beginTransaction(String who) {
LogHelper.WriteLogDebug("starting transaction by " + (who == null ? "null" : who));
try {
//in this way if a transaction is still executing it waits untill the previus ends.
//obviously every time i call DbManager.beginTransaction the call at DbManager.endTransaction is in the finally statment
if (_db.inTransaction()) {
LogHelper.WriteLogInfo("DB IS IN TRANSACTION");
synchronized (lock) {
lock.wait();
}
}
getDB().beginTransactionWithListener(new SQLiteTransactionListener() {
@Override
public void onRollback() {
synchronized (lock) {
LogHelper.WriteLogInfo("onRollback listener invoked");

Solution

The code looks fine to me but it is a bit odd because the official docs recommend creating a SQLiteOpenHelper subclass to handle database interaction. And if you use one SQLiteOpenHelper instance across your application, it will be thread-safe so there's no need to add your own synchronization logic:

public class DatabaseHelper extends SQLiteOpenHelper {

  private static final String DATABASE_NAME = "location_scout.db";
  private static final int SCHEMA_VERSION = 1;

  // Singleton pattern
  private static DatabaseHelper instance;
  public synchronized static DatabaseHelper getInstance(Context context) {
      if(instance == null) {
          instance = new DatabaseHelper(context.getApplicationContext());
      }
      return instance;
  }

  private DatabaseHelper(Context context) {
      super(context, DATABASE_NAME, null, SCHEMA_VERSION);
  }

}

Code Snippets

public class DatabaseHelper extends SQLiteOpenHelper {

  private static final String DATABASE_NAME = "location_scout.db";
  private static final int SCHEMA_VERSION = 1;

  // Singleton pattern
  private static DatabaseHelper instance;
  public synchronized static DatabaseHelper getInstance(Context context) {
      if(instance == null) {
          instance = new DatabaseHelper(context.getApplicationContext());
      }
      return instance;
  }

  private DatabaseHelper(Context context) {
      super(context, DATABASE_NAME, null, SCHEMA_VERSION);
  }

}

Context

StackExchange Code Review Q#28605, answer score: 6

Revisions (0)

No revisions yet.