I’m using the SQLiteOpenHelper (shown below) in all my apps quiet happily. Lots of upgrades to existing databases ended successful in many year.
This time I need to upgrade the database in one of my apps and this step will last for some time. So I need to put these upgrade statements in their own thread.
What’s the best place to do so?
Any help is highly appreciated.
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
protected static final Object lock = new Object();
private static final int DATABASE_NAME = "mydatabase.db";
private static final int DATABASE_VERSION = 3;
private Context context;
private SQLiteDatabase database;
public MySQLiteOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase database) {
synchronized (lock) {
this.database = database;
// Create database statements
}
}
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
synchronized (lock) {
this.database = database;
switch (newVersion) {
case DATABASE_VERSION:
switch (oldVersion) {
case 1:
upgradeFrom1To2();
case 2:
upgradeFrom2To3();
}
break;
}
}
}
private void upgradeFrom1To2() {
// Upgrade database statements
}
private void upgradeFrom2To3() {
// Upgrade database statements
}
}
I’d put the code in an IntentService, which is an easy way to implement a background thread for a long-running operation, especially one that is saving data. Use broadcast Intent to send status from the IntentService to other components, and BroadcastReceiver to receive these Intent, if you need to.
I would really avoid doing this in AsyncTask within an Activity; there’s too much risk that the operation would be killed. Anyway, AsyncTask is much more complicated than IntentService.
One note: IntentService doesn’t persist anything, including its class fields. To protect yourself, you may want to store state in SharedPreferences.