Android SQLiteOpenHelper: 为什么onCreate()方法没有被调用?

60

我正在尝试创建我的第一个安卓应用。我注意到如果数据库不存在,SQLiteOpenHelper.onCreate() 方法不会被调用来创建表。然而,即使我尝试进行调试,onCreate() 方法也没有起作用。

请查看下面的代码并给我任何建议。非常感谢您的帮助。

public class NameToPinyinActivity extends Activity {

    DatabaseOpenHelper helper = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nametopinyin);

        Button searchButton = (Button) findViewById(R.id.search);
        searchButton.setOnClickListener(new ButtonClickListener());

        helper = new DatabaseOpenHelper(NameToPinyinActivity.this);
    }

public class DatabaseOpenHelper extends SQLiteOpenHelper {

    /** DB Name */
    private static final String DB_NAME = "pinyin";

    /** CREATE TABLE SQL */
    private static final String CREATE_TABLE_SQL = "CREATE TABLE UNICODE_PINYIN"
            + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, "
            + "UNICODE TEXT NOT NULL, PINYIN TEXT NOT NULL)";

    public DatabaseOpenHelper(Context context) {
        super(context, DB_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.beginTransaction();
        try {
            db.execSQL(CREATE_TABLE_SQL);
            db.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            db.endTransaction();
        }
    }

你试过放置一个日志语句并查看吗?你怎么确定onCreate()被调用了?如果你设置断点,根据我的观察,它们不太可能到达DB helper中的那个方法。 - Suchi
10个回答

66

我也曾遇到过使用SQLiteOpenHelper的困难。对我有用的是存储成员变量。

SQLiteDatabase db;

在SQLiteOpenHelper子类中进行调用

 db = getWritableDatabase();

在构造函数中。

这个问题的答案还包括有用的信息:SQLiteOpenHelper failing to call onCreate?

希望这能帮到你!


是的!你说得对!我可以制作数据库,你提到的参考资料非常有帮助。谢谢! - zono
1
db = getWritableDatabase(); - 对我来说,它只会触发 onUpgrade,但不会触发 onCreate。有什么提示吗? - kellogs
8
这意味着数据库已经被创建了。只有在数据库不存在时才会调用onCreate()方法。 - Kevin King
getDatabase called recursively - jose920405
一旦我添加了这行代码 db = getWritableDatabase();,onCreate 就起作用了,数据库也被创建了。 - RobertoFRey

27

只有在调用SQLiteOpenHelper类的getWritableDatabase()getReadableDatabase()方法之后,数据库才会被创建。

就像这样,当你实际需要时,数据库将在内存中创建:)


6

我曾经遇到过一个类似的问题,即onCreate()方法没有被执行。也许这对某个人有用,即使最终结果是不同的问题。

我之前一直在处理数据库,而且早就创建了一个数据库。所以现在,在修改完onCreate()方法后,我希望找到新创建的数据表。但SQLiteOpenHelper从未再次调用onCreate()方法,原因是数据库已经存在。我仍然在使用与之前相同的设备,因此仍在使用已经存在的(旧)数据库。

但还有一线希望。当系统发现具有该名称的数据库已经存在时,它还会检查版本号是否正确。在这种情况下,我只是忘记了数据库已经存在。我的解决方案很简单,就是更改版本号。因此,onUpgrade()方法被调用,提供了对onCreate()方法进行更改的选项。

因此,可选的方法是卸载整个应用程序(并随之卸载数据库),或者在升级版本号后再次调用onCreate()方法(例如删除旧表并再次调用onCreate()方法)。

无论如何,如果onCreate()方法没有被调用,请检查数据库是否存在。否则,它将不会再次被调用。


非常好的解决方案!在看到这个之前,我也卸载了几次应用程序。 :-) - ankush981

1
在构造函数中调用getWritableDatabase()。保留HTML,不要解释。
public DataBaseH(@Nullable Context context) {
    super(context, dataBaseName, null, dataBaseVersion);
    SQLiteDatabase db=this.getWritableDatabase();

}

@Override
public void onCreate(SQLiteDatabase db) {
 String createTable="CREATE TABLE IF NOT EXISTS "+tableName+                              " ( "+
            id+  " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"+
            name+                              " TEXT,"+
            familyName+                        " TEXT,"+
            age+                           " INTEGER);";

    db.execSQL(createTable);

     Log.i(TAG,"db.exect");


}

1
我曾经遇到过类似的问题,但问题不在于 OnCreate 调用。如上面的代码示例中,Kevin 解释了如果数据库已经存在,则不会调用 OnCreate。然而,如果像我一样,您正在使用来自不同活动的多个表格,那么尽管您可能已经创建了数据库,但与此活动关联的表格可能尚未被创建。因此,当您尝试在不存在的表格上设置游标数据时,将引发异常。
我的解决方案是定义一个名为 CreateTable 的单独类,该类既从 OnCreate 覆盖中调用,也从

db = getWritableDatabase();

之后的构造函数中调用。


1
我曾经遇到一个类似的问题,即当应用程序第一次运行时onCreate()未执行,因此我的数据库从未被创建。这与onCreate()未执行因为数据库已经存在不同,因为数据库尚不存在。具体来说,我的DataProvider onCreate()未执行,所以OpenHelper也没有被调用。
我验证了之前答案中描述的所有设置,但没有解决我的问题。如果有人像我一样忘记了一个小细节,我在此发布此答案。
对我有用的解决方法是在AndroidManifest.xml中为我的数据提供程序添加一个条目,嵌套在标签内,以及所有的条目。我所需要的唯一属性是:
  • android:name=".DataManagement.DbDataProvider"
  • android:authorities="com.example.myApplicationName.DataManagement.DbDataProvider"
  • android:exported="false"

请确保更改上述属性的值以匹配您的项目

我清理了数据提供程序和打开辅助类的构建、运行和onCreate()方法,这些方法都已正确执行,并且数据库在第一次应用程序启动时已创建!


0

我曾经遇到过同样的问题... 对我来说解决方法是在数据库名称后面添加 .db 扩展名


-1
在我的情况下,它没有被调用是因为数据库已经存在了!所以,如果可能的话,请确保删除您的应用程序并重新安装它,然后再检查它是否被调用。

-1

我曾经遇到过同样的问题,似乎onCreate没有被执行。我之所以这么认为是因为我的日志没有显示出来。结果发现我的SQL_create字符串中有一些空格出了问题。

@Override
public void onCreate(SQLiteDatabase db) {
    try {
        Log.d(LOG_TAG, "A table is created with this SQL-String: " + SQL_CREATE + " angelegt.");
        db.execSQL(SQL_CREATE);
    }
    catch (Exception ex) {
        Log.e(LOG_TAG, "Error when creating table: " + ex.getMessage());
    }
}

这是我纠正后的SQL语句:

enterpublic static final String SQL_CREATE =
        "CREATE TABLE " + TABLE_VOCAB_LIST +
                "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_GERMAN + " TEXT NOT NULL, " +
                COLUMN_SPANISH + " INTEGER NOT NULL, "+
                COLUMN_LEVEL + " INTEGER NOT NULL);)"; code here

我忘记了一个空格,当我添加它时一切都正常工作了。


-2

您可以将AUTOINCREMENT更改为AUTO INCREMENT

注意: 当第一次创建数据库时,SQLiteOpenHelper会调用onCreate方法。如果您在onCreate方法中创建表,则无法创建新的SQLiteDatabase。您可以参考以下示例:

    @Override
    public void onCreate(SQLiteDatabase db) {
        String stringCreateTable = "CREATE TABLE "+"tblUser"+" ( " +
                "id TEXT PRIMARY KEY, " +
                "name TEXT )";
        db.execSQL(stringCreateTable);
    }


5
“你可以将AUTOINCREMENT更改为AUTO INCREMENT。” “不,你不能这样做!” - Anup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接