SQLiteOpenHelper failing to call onCreate?
Asked Answered
A

4

31

I am trying to create a local database on an android phone using sqlite.

I have a helper class, shown below, that is used to create the database and provide the "help".

I am wanting to create an object of this class in the main part of my code and it create the database and tables there as well.

The problem:

Whenever i create an object of the class, it does not seem to be calling the onCreate method in the helper. I thought this is supposed to happen. I thought that onCreate was basically a constructor for the class. (I believe i am wrong)

  • So, why is it not calling the onCreate method?
  • Or how do i get it to create the database and tables where i am creating the object of the class?
  • What would be a better way to do this, if this is not a good approach?

public class SmartDBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "smart_lite_db.db";
    private static final int DATABASE_VERSION = 2;
    private static final String NOTIFY_TABLE_NAME = "user_notify_data";
    private static final String HR_TABLE_NAME = "user_hr_data";
    private static final String NOTIFY_TABLE_CREATE = 
        "CREATE TABLE " + NOTIFY_TABLE_NAME + 
        " (counter INTEGER PRIMARY KEY, " + 
        "userresponse INTEGER, " + 
        "notifytime INTEGER);";
    private static final String DATA_TABLE_CREATE = 
        "CREATE TABLE " + HR_TABLE_NAME +
        " (counter INTEGER PRIMARY KEY, " +
        "hr INTEGER, " +
        "act INTEGER, " +
        "timestamp INTEGER);";      

    public SmartDBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        // TODO Auto-generated constructor stub
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        Log.v("smartdbhelper", "before creation");
        db.execSQL(NOTIFY_TABLE_CREATE);
        Log.v("smartdbhelper", "middle creation");
        db.execSQL(DATA_TABLE_CREATE);
        Log.v("smartdbhelper", "after creation");
    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

public class SmartApp extends Activity implements OnSharedPreferenceChangeListener {
   private SmartDBHelper dBHelper;
   public void onCreate(Bundle savedInstanceState) {
      //where i am wanting to create the database and tables
      dBHelper = new SmartDBHelper(getContext());
   }
}
Amann answered 17/2, 2011 at 1:38 Comment(0)
A
70

The onCreate is not a constructor for the database class. It is only called if you try to open a database that does not exist. To open/create the database you need to add a call to one of these methods:

public class SmartApp extends Activity implements OnSharedPreferenceChangeListener {
   private SmartDBHelper dBHelper;
   public void onCreate(Bundle savedInstanceState) {
      //where i am wanting to create the database and tables
      dBHelper = new SmartDBHelper(getContext());
      // open to read and write
      dBHelper.getWritableDatabase();
      // or to read only
      // dBHelper.getReadableDatabase();
   }
}

It is a bit big but here is my DatabaseAdapter you can take a look at: http://saintfeintcity.org/projects/sfc/repository/entry/trunk/src/org/saintfeintcity/database/GameDbAdapter.java

Aquileia answered 17/2, 2011 at 1:48 Comment(8)
Cool, thanks. If i am wanting to have a class, like yours, that holds all my sql handling stuff. How do i gain access to the object of that class in all my other classes? For instance, i create the object in my main class. Now i want to use the insert methods in a class that was created in my main class. How do i access the original db object that was created in the main class in another class?Amann
Actually, do i just create a new object inside each class that needs the databaseHelper? I believe this is what i am supposed to do, i may ask this as a questions if no one replies. ThanksAmann
im facing a problem here ..02-17 10:12:53.441: ERROR/Database(311): close() was never explicitly called on database '/data/data/com.ey.eyconnect/databases/test.db' 02-17 10:12:53.441: ERROR/Database(311): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here exception is thrown here..how to resolve this...Delacruz
I resolved the exception. I was calling db = eventsData.getReadableDatabase(); twice thats why the exception is thrownDelacruz
@prolink: Take a look at the class GameApplication of my project and the manifest. My own Application implementation handles the open/close and the holding of the database object.Aquileia
@Aquileia why this doesn't work for me...I have used similar code as yours, but code in onCreate is not executed at all...Ivan
It must be executed. If not, you are not starting the right activity.Aquileia
I found that onCreate is called only when the app is first launched. After that, the database file exists and Android knows it shouldn't call onCreate again (that's my guess anyway). I uninstalled the app and relaunched it from Eclipse and finally saw the expected Logcat messages from within onCreate.Monosome
C
14

You have to call getWritableDatabase() or getReadableDatabase().

Carving answered 17/2, 2011 at 1:43 Comment(1)
testing now, i believe you are right. I just checked the android examples and found that. I must have been over looking it, will let you know how it goes. ThanksAmann
S
2

oncreate() method is not a constructor and also Called when the database is created for the first time.So you have to call getWritableDatabase() or getReadableDatabase() for open or create to your database.

getReadableDatabase() :- Create and/or open a database.

getWritableDatabase() :- Create and/or open a database that will be used for reading and writing.

Scotfree answered 14/9, 2018 at 6:21 Comment(0)
E
0

One reason SQLiteOpenHelper.onCreate() doesn't get called is because the database file already exists on the device.

If you go to View > Tool Windows > App Inspection in Android Studio, you can go to Database Inspector and see the SQLite files on the device.

In the case where onCreate is not being called because there's an existing database with that name already, you can change the database name in your app to something new. Then database file won't exist, and so onCreate will get called.

static class MyDatabaseHelper extends SQLiteOpenHelper {
    private DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION); // A new DB_NAME here means onCreate() will get called.
        mDatabaseHelper = this;
    }
    ....
    ....
}

If the above DB_NAME is something never used before, onCreate() should run, but if you're trying to re-use a name, it already exists, and onCreate() won't run.

I found the easiest thing to do is just keep making new DB_NAMEs as you're iterating through app development.

Escallop answered 2/12, 2023 at 19:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.