【问题标题】:Android - Can't create instance of DatabaseAndroid - 无法创建数据库实例
【发布时间】:2014-06-20 08:24:31
【问题描述】:

我正在关注 Google 员工制作的 this 教程。

如果您查看第三个代码 sn-p,本教程显示了从 SQLiteOpenHelper 类扩展而来的 FeedReaderDbHelper 类。

public class FeedReaderDbHelper extends SQLiteOpenHelper

然后,它展示了如何创建FeedReaderDbHelper 对象的实例,以便使用它来读取和写入数据库。

FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

我看到的问题是SQLiteOpenHelper 是一个抽象类。所以每当我在我的自己的程序中执行以下操作时:

MatchEntry.MatchDBHelper dbHelper = new MatchEntry.MatchDBHelper(context);

我收到一个错误:....MatchContract.MatchEntry is not an enclosing class

这是因为SQLiteOpenHelper 是抽象的吗?我设置课程的方式完全相同,并且几乎完全模仿了文档的内容。

更新

这是目前结构的样子:

public class MatchContract {

    public MatchContract() {
    }

    public static abstract class MatchEntry implements BaseColumns {
        ...
        ...
        ...
    }

    public class MatchDBHelper extends SQLiteOpenHelper {
        ...
        ...
        ...
    }
}

MatchDBHelper 放在MatchContract 类中是否正确?我假设它需要知道SQL_CREATE_TABLE 字符串,否则它不会知道。

【问题讨论】:

  • MatchDBHelper 不能是内部类,我想。我也做了那个教程。给你了,看看吧。您将看到合同与 sqlHelper 类分开:github.com/algui91/CursoAndroid/tree/master/Ejemplos/…
  • @algui91 - 啊啊好吧。那么我必须为每个条目创建一个DBHelper 吗?例如:StudentDBHelperClassDBHelperCarDBHelper?

标签: android database sqliteopenhelper


【解决方案1】:

这个想法是,Contract 类是数据库的抽象,因此,在MatchContract 中,您将拥有数据库的所有全局变量,而在内部类中,MatchEntry 您将实现抽象数据库本身(列等)。然后,使用MatchDBHelper,您将管理数据库(创建、升级等)并编写 SQL 条目。

正如我在 cmets 中所说,您需要将帮助类创建为普通类,而不是内部类:

public class MatchContract {

public MatchContract() {
}

/// Global variables for the DB

    public static abstract class MatchEntry implements BaseColumns {
    // Structure of the database
    }
}


public class MatchDBHelper extends SQLiteOpenHelper {
    // Manage the database
}

作为一个完整的例子:

public final class PersonContract {

    public PersonContract() {
    }
    public static abstract class PersonEntry implements BaseColumns{
        public static final String TABLE_NAME = "person";
        public static final String COLUMN_NAME_ENTRY_ID = "personID";
        public static final String COLUMN_NAME_FIRST_NAME = "firstname";
        public static final String COLUMN_NAME_SECOND_NAME = "secondname";
    }
}

public class PersonDbBHelper extends SQLiteOpenHelper {

    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "Persons.db";

    private static final String TEXT_TYPE = " TEXT";
    private static final String COMMA_SEP = ",";

    private static final String SQL_CREATE_ENTRIES =
            "CREATE TABLE " + PersonEntry.TABLE_NAME + " (" +
                    PersonEntry._ID + " INTEGER PRIMARY KEY," + // Heredado de BaseColumns
                    PersonEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
                    PersonEntry.COLUMN_NAME_FIRST_NAME + TEXT_TYPE + COMMA_SEP +
                    PersonEntry.COLUMN_NAME_SECOND_NAME + TEXT_TYPE  +
                    " )";

    private static final String SQL_DELETE_ENTRIES =
            "DROP TABLE IF EXISTS " + PersonEntry.TABLE_NAME;


    public PersonDbBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}

【讨论】:

  • 谢谢@algui91。你能告诉我是否必须为每个条目创建一个 DBHelper 吗?例如:StudentDBHelper、ClassDBHelper、CarDBHelper?
  • @Subby 您需要为每个数据库而不是每个表创建一个 DBHelper。
  • 嗯,对了,所以我需要扩展 SQL_CREATE_ENTRIES 以便它包含我拥有的所有表?
  • @Subby 我认为每张表有一个 SQL_CREATE 会更有条理,然后在onCreatedb.execSQL(SQL_CREATE_TABLE1); db.execSQL(SQL_CREATE_TABLE2);...我从来没有在android中创建一个有多个表的数据库,但是我认为这是一个很好的方法。
  • 明白了!非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 2015-02-10
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
  • 1970-01-01
相关资源
最近更新 更多