编辑2,问题解决了 - 问题是我有两个不同的帮助器,一个用于单个数据库中的每个表。 这意味着当第一个帮助器被实例化时,它的onCreate方法被调用,并且数据库与一个表一起创建。
当第二个帮助器被实例化时,没有调用onCreate方法,因为数据库已经存在。这意味着未创建第二个表,因此在尝试访问第二个表时会引发错误。
编辑,我想我已经意识到我的问题 - SQLiteHelper引用的是数据库而不是表。我不应该有多个帮助器,只管理所有表。 有两个帮助器导致第二个onCreate方法不被调用,因为数据库已经存在。
我有一个数据库的助手类。 活动按如下方式创建它的实例 -
storageHelper = new ClassTimeStorageHelper(getApplicationContext());
接下来,调用一个方法来加载数据持有者类的ArrayList -
classes = storageHelper.getAllClasses();
被调用的方法如下 -
public ArrayList<ClassTime> getAllClasses() {
ArrayList<ClassTime> classes = new ArrayList<>();
String query = "SELECT * FROM " + TABLE_CLASS_TIMES;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
ClassTime c;
if (cursor.moveToFirst()) {
do {
c = new ClassTime();
c.setId(Integer.parseInt(cursor.getString(0)));
c.setSubjectID(cursor.getInt(1));
c.setStart(cursor.getInt(2));
c.setEnd(cursor.getInt(3));
c.setDay(cursor.getInt(4));
classes.add(c);
} while (cursor.moveToNext());
}
Log.d("getAllClasses", classes.toString());
return classes;
}
存储助手的onCreate方法是 -
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("OnCreate", "Method called");
try {
String CREATE_TABLE_CLASS_TIMES = "CREATE TABLE IF NOT EXISTS " +
TABLE_CLASS_TIMES +
"(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_LESSON_ID + " INTEGER, " +
"FOREIGN KEY(" + KEY_LESSON_ID + ") " + "REFERENCES " + TABLE_SUBJECTS + "(id), " +
KEY_START_TIME + " INTEGER, " +
KEY_END_TIME + " INTEGER, " +
KEY_DAY + " INTEGER )";
db.execSQL(CREATE_TABLE_CLASS_TIMES);
} catch (Exception e) {
Log.d("Exception ", ""+e.getStackTrace());
}
}
由于缺少日志语句,我可以看到onCreate方法没有被调用,即使我清除了应用程序数据,或者卸载并重新安装。 编辑 - 我还尝试创建一个全局SQLiteDatabase变量,并在构造函数中调用db = this.getWriteableDatabase(),然后替换对此方法的其他调用。同样的问题仍然存在。
我不明白什么是错的,因为我有另一张桌子非常相似的帮手 -
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE_SUBJECT = "CREATE TABLE IF NOT EXISTS " +
TABLE_SUBJECT +
"(" + KEY_ID + " Integer PRIMARY KEY AUTOINCREMENT, " +
KEY_SUBJECT_NAME + " VARCHAR, " +
KEY_CLASSROOM + " VARCHAR, " +
KEY_TEACHER + " VARCHAR, " +
KEY_COLOR + " Integer )";
db.execSQL(CREATE_TABLE_SUBJECT);
}
public ArrayList<Subject> getAllSubjects() {
ArrayList<Subject> subjects = new ArrayList<>();
String query = "SELECT * FROM " + TABLE_SUBJECT;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Subject l;
if (cursor.moveToFirst()) {
do {
l = new Subject();
l.setId(Integer.parseInt(cursor.getString(0)));
l.setName(cursor.getString(1));
l.setClassroom(cursor.getString(2));
l.setTeacher(cursor.getString(3));
l.setColor(cursor.getInt(4));
subjects.add(l);
} while (cursor.moveToNext());
}
Log.d("getAllSubjects", subjects.toString());
return subjects;
}
它没有任何问题。
日志如下 -
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/SQLiteLog: (1) no
such table: ClassTimes
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement D/AndroidRuntime: Shutting down VM
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: FATAL EXCEPTION: main
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: Process: com.anapp.tpb.replacement, PID: 1238
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.anapp.tpb.replacement/com.anapp.tpb.replacement.Setup.DataPresentation.ClassTimeCollector}: android.database.sqlite.SQLiteException: no such table: ClassTimes (code 1): , while compiling: SELECT * FROM ClassTimes
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.-wrap11(ActivityThread.java)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: Caused by: android.database.sqlite.SQLiteException: no such table: ClassTimes (code 1): , while compiling: SELECT * FROM ClassTimes
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1255)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at com.anapp.tpb.replacement.Storage.StorageHelpers.ClassTimeStorageHelper.getAllClasses(ClassTimeStorageHelper.java:111)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at com.anapp.tpb.replacement.Setup.DataPresentation.ClassTimeCollector.onCreate(ClassTimeCollector.java:87)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6237)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.-wrap11(ActivityThread.java)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
02-20 19:59:58.370 1238-1238/com.anapp.tpb.replacement E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
答案 0 :(得分:3)
SQLiteOpenHelper
用于版本化数据库文件,而不是表格。如果数据库中有多个表,请将它们全部放在同一个帮助程序中。
CREATE TABLE
中存在语法问题。外键定义应该在末尾,而不是与列定义混合。
您有try
- catch
隐藏语法问题。去掉它。如果出现问题,onCreate()
不能正常返回,但会抛出异常。
修复上述内容后,请再次卸载您的应用,以删除使用损坏的onCreate()
创建的空数据库。
答案 1 :(得分:2)
首先打开数据库, 即SQLiteDatabase db = this.getWritableDatabase(); 然后执行CRUD操作。
所以,改变
String query = "SELECT * FROM " + TABLE_CLASS_TIMES;
SQLiteDatabase db = this.getWritableDatabase();
to
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_CLASS_TIMES;