如果未创建数据库,我想在应用程序启动时创建数据库表,因此在这些表中创建表和插入初始值的调用都放在扩展SQLiteOpenHelper的类中的OnCreate方法中。
问题是在应用程序启动时,我不对数据库执行任何操作(我只创建了一个从我的主活动java类扩展SQLiteOpenHelper的类的新实例),因此OnCreate方法不会自动触发,因此数据库未创建。
扩展SQLiteOpenHelper的类(DBHelper)的构造函数是(Context来自app的主要活动java类):
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.activityContext = context;
}
因此,为了触发onCreate方法并强制创建数据库(如果它不存在),一旦我创建了一个扩展SQLLiteOpenHelper的类的新实例:
MyDbHelper = new DBHelper(MainActivity.this);
我打电话给下面的方法:
MyDbHelper.SetWritableDb();
执行以下操作:
this.getWritableDatabase();
执行上述sentece后,将触发OnCreate方法,并通过CREATE语句创建数据库。好的,直到这里没问题。
在创建数据库表之后,我然后为某些表设置了一些默认值,也就是说,我执行了一些插入但抛出了异常:
java.lang.IllegalStateException: getDatabase called recursively
我认为问题是当使用下面的方法向某些表插入默认值时(从扩展SQLiteOpenHelper的类调用此方法):
public final boolean BulkInsert(Context context, DBHelper dbHelper)
{
boolean result = false;
SQLiteDatabase db = dbHelper.getWritableDatabase();
.....
}
再次调用getWritableDatabase,因此数据库试图再次被阻止:
android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked
然后它崩溃....
我怎样摆脱这个?当我的应用启动时,我需要在主要活动中创建我的SQLite数据库(如果它尚未创建)。
答案 0 :(得分:2)
如您所知,onCreate()
由getWritableDatabase()
触发。
您无法在getWritableDatabase()
来电中致电onCreate()
。这样做会导致"递归调用"例外。将SQLiteDatabase
对象作为参数提供给onCreate()
,而不是调用getWritableDatabase()
。
关于getDatabaseLocked()
的另一个问题 - 我猜测它是NPE,是由于您向null
提供Context
或其他无效SQLiteOpenHelper
造成的构造