【问题标题】:Android SQLiteOpenHelper: Why onCreate() method is not called?Android SQLiteOpenHelper:为什么不调用 onCreate() 方法?
【发布时间】:2011-07-22 14:55:19
【问题描述】:

我正在尝试制作我的第一个 Android 应用。我注意到如果数据库不存在,则不会调用 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();
        }
    }

【问题讨论】:

  • 你有没有试过放个log语句看看?是什么让您确定 onCreate() 被调用?在我的观察中,如果设置断点,它们往往不会在 DB 助手中达到该方法。

标签: java android android-sqlite


【解决方案1】:

我也遇到了 SQLiteOpenHelper 的问题。对我有用的是存储一个成员变量

SQLiteDatabase db;

在 SQLiteOpenHelper 子类中并调用

 db = getWritableDatabase();

在构造函数中。

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

我希望这会有所帮助!

【讨论】:

  • 是的!你说的对!我可以制作数据库,您提到的参考资料非常有帮助。谢谢!
  • db = getWritableDatabase(); - 对我来说,它只会触发 onUpgrade,但不会触发 onCreate。有什么提示吗?
  • 表示数据库已经创建好了。只有当数据库不存在时才会调用 onCreate()。
  • getDatabase called recursively
  • 只要我添加了这行代码 db = getWritableDatabase();,onCreate 就起作用了,数据库就创建好了。
【解决方案2】:

在调用SQLiteOpenHelper 类的getWritableDatabase()getReadableDatabase() 方法之前,不会创建数据库。

当您真正需要时,将在内存中创建该数据库一样简单。:)

【讨论】:

    【解决方案3】:

    我遇到了类似的问题,即未执行 onCreate。也许这对某人有任何用处,即使结果证明这是一个不同的问题。

    我之前正在处理数据库,并且很久以前就已经创建了一个。所以现在在 onCreate() 进行更改后,我希望找到创建的新表。但是 SQLiteOpenHelper 再也没有调用 onCreate() 了。原因是,数据库已经存在。我仍在使用与以前相同的设备,因此使用已经存在的(旧)数据库。

    但还是有希望的。当系统发现同名的数据库已经存在时,它还会检查版本号是否正确。在那种情况下,我只是忘记了数据库已经存在。我的解决方案只是更改版本号。因此 onUpgrade() 被称为提供 onCreate() 更改的选项。

    所以选项要么卸载整个应用程序(以及数据库),要么在升级版本号(例如删除)旧表并再次调用 onCreate() 后再次调用 onCreate。

    在任何情况下,如果没有调用 onCreate(),请检查两次数据库是否存在。否则不会再次调用。

    【讨论】:

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

    我遇到了类似的问题,但问题不是OnCreate 调用。

    在上面的示例代码中,Kevin 解释说,如果数据库已经存在,则不会调用 OnCreate。但是,如果像我一样,您正在使用来自不同活动的多个表,那么尽管您可能已经创建了数据库,但与此活动关联的表可能尚未创建。因此,当您尝试在不存在的表上设置游标数据时,您将调用异常。

    我的解决方案是定义一个名为 CreateTable 的单独类,该类既可以从 OnCreate 覆盖,也可以从

    之后的构造函数调用

    db = getWritableDatabase();

    【讨论】:

      【解决方案5】:

      调用 getWritableDatabase();在构造函数中

      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");
      
      
      }
      

      【讨论】:

        【解决方案6】:

        当应用程序第一次运行时,我遇到了类似的问题,onCreate() 没有执行,所以我的数据库从未被创建。这与 onCreate() 未执行时不同,因为数据库已经存在,因为数据库尚不存在。具体来说,我的 DataProvider onCreate() 没有执行,所以 OpenHelper 也没有被调用。

        我确认我已经按照之前答案中每个人描述的方式进行了所有设置,但没有解决我的问题。发布此答案以防其他人像我一样忘记了一个小细节。

        为我解决问题的是在 AndroidManifest.xml 中为我的数据提供者添加一个条目,嵌套在标签内,以及我的所有条目。我需要的唯一属性是:

        • android:name=".DataManagement.DbDataProvider"
        • android:authorities="com.example.myApplicationName.DataManagement.DbDataProvider"
        • android:exported="false"

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

        我为数据提供者清理、构建、运行和 onCreate() 方法并正确执行了打开的帮助程序类,并且在首次应用程序启动时创建了数据库!

        【讨论】:

          【解决方案7】:

          我遇到了同样的问题.. 我的解决方案是添加 .db 作为数据库名称的扩展名

          【讨论】:

            【解决方案8】:

            在我的例子中,它没有被调用,因为数据库已经存在!因此,如果可能,请确保删除您的应用并重新安装它,然后再检查它是否被调用。

            【讨论】:

              【解决方案9】:

              我遇到了同样的问题,似乎没有执行 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
              

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

              【讨论】:

                【解决方案10】:

                您可以将 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);
                    }

                【讨论】:

                • "您可以将 AUTOINCREMENT 更改为 AUTO INCREMENT" 不,您不能!!
                猜你喜欢
                • 1970-01-01
                • 2013-03-13
                • 2012-12-06
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-06-28
                • 1970-01-01
                • 2016-09-17
                相关资源
                最近更新 更多