I need to know where to call the db.close() in my code. I\'ve added it on onCreate() method, but when I need to use some methods it says database not open, and then I\'ve remove
if you open in onCreate, then close in onDestroy
I think there are 2 ways:
onPause
-method and check there isFinishing
if yes -> close. Problem: if your app gets killed by app-killer, db remains open. EDIT:
Ok, I see why it could be caused. I think you misunderstood the usage of the SQLiteOpenHelper
. You never have to call the onCreate
-method.
Defently the better way is to make a DBHelper
class and use it in a separate calls, lets say SQLDataHandler
.
Your activity look good. I changed a few things, look if it helps. I'll mark them:
That's all what should be in the Helper class:
public static class OpenHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "database.db";
private static final int DATABASE_VERSION = 1;
protected static final String TABLE_NAME = "table";
protected String TAG = "HoursPerDayDataHelper";
Just leave it CREATE TABLE
it gets only created/called if there isn't one existing.
I have seen errors occurring if the String is passed directly
@Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE "
+ TABLE_NAME
+ "(id INTEGER PRIMARY KEY AUTOINCREMENT, duration TIME, date DATE, current_time TIME)";
db.execSQL(query);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
To use it:
Just call in your DataHandler
class :
OpenHelper helper = new OpenHelper(ctx);
// SQLiteDatabase db = helper.getReadableDatabase();
SQLiteDatabase db = helper.getWritableDatabase();
All other stuff, like deleting, adding and so on, should be done in a "DataHandler" class.
Just use the same two methods there to get your DB. At the end, when you are finished, you call just in you DataHandler
class db.close()
.
Like this the activity itself never uses de DB directly. Better practice I think ;)
I hope it helps. For any other questions, just ask :)
EDIT2:
First, in general it should work with a inner class.
BUT: In case you want to add another table from another class it won't work anymore. Thats why it's the better way to put it in a separate class from beginning. It's even reusable (with some smal adjustments).
Put the code I posted in your class OpenHelper. Nothing more.
Then, put the data manipulation stuff in a class called something like: DataHandlerDB.
Code example:
package ...;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DataHandlerDB {
public static void persistAll(Context ctx, List<Module> moduleList) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
for (Module m : moduleList) {
values.put("_id", m.get_id());
values.put("name", m.getModule());
db.insert("module", null, values);
}
db.close();
}
public static List<Module> findAll(Context ctx) {
List<Module> result = new ArrayList<Module>();
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query(ModuleDB.TABLE_NAME, new String[] { ModuleDB.ID,
ModuleDB.MODULE}, null, null, null, null, null);
while (c.moveToNext()) {
Module m = new Module(c.getInt(0), c.getString(1));
result.add(m);
}
c.close();
db.close();
return result;
}
// Update Database entry
public static void update(Context ctx, Module m) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("_id", m.get_id());
values.put("name", m.getModule());
db.update("module", values, null, null);
db.close();
}
public static void delete(Context ctx, Module m) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("_id", m.get_id());
values.put("name", m.getModule());
db.delete("module","_id = m.get_id()", null);
db.close();
}
public static void createDB(Context ctx) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
db.close();
}
}
In order to be more efficient the methods are static
, you won't need to create objects.
Use it like this: In your activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get the a writable DB, in case it's not existing it gets created.
DataHandlerDB.createDB(this);
// get stuff out of DB
moduleList = DataHandlerDB.findAll(this);
adapter = new ArrayAdapter<Module>(this,
android.R.layout.simple_list_item_1, moduleList);
setListAdapter(adapter);
}