当通过首次打开数据库触发OnCreate时,无法从SQLIte Helper Oncreate打开SQLite数据库

当mainactivity在安装应用程序后第一次尝试打开数据库时,会触发SQLiteHelper Oncreate方法(正如人们所期望的那样)。 我想在OnCreate中创建数据表之后填充数据库,但这样做需要我在我的内容创建者类(从OnCreate调用)中再次打开数据库。 当应用程序尝试在内容创建者类中打开数据库时,应用程序崩溃

基本上我是在创建数据库时尝试填充数据库,但显然不是正确的方式。

来自SQLiteHelper类

@Override public void onCreate(SQLiteDatabase db) { db.execSQL(SQL_CREATE_TABLE); //sql string to create the table dbContents.baseContents(sqcontext); } 

来自内容创建者类

 public class dbContents { public static void baseContents(Context context) { dbDataSource ds = new dbDataSource(context); ds.open(); 

从dbDataSource类

 public dbDataSource(Context context) { dbHelper = new MySQLiteHelper(context); DatabaseVersion = dbHelper.DatabaseVersion; //used when MainActivity onResume to know if it needs to repopulate reminders } public void open() throws SQLException { database = dbHelper.getWritableDatabase(); //crashes here } 

它似乎在第database = dbHelper.getWritableDatabase()行崩溃; 在open()方法中。 重申一下,在主活动中打开数据库时会调用SQLiteHelper OnCreate。 当在mainactivity中打开数据库时,它调用上面发布的同一个open()方法,当从dbcontents类调用它时崩溃。 这是一个线程问题吗?

我编写了一些代码片段,可以帮助您填充SQLite Database , Github上的代码可以查看工作示例。

创建一个类名CreateDatabase.java ,它的全部目的是创建数据库并向其中添加一个表。

 public class CreateDatabase extends SQLiteOpenHelper implements BaseColumns { private static final String DATABASE_NAME = "database_name.sqlite"; private static final int DATABASE_VERSION = 1; public static final String TEXT_TYPE = " TEXT"; public static final String COMMA_SEP = ","; public CreateDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { Log.d("CreateDatabase: ","onCreate: called for the first time"); db.execSQL(SQL_CREATE_TEST_ONE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public static final String SQL_CREATE_TEST_ONE_TABLE = "CREATE TABLE IF NOT EXISTS " + "TestOne_Table" + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY," + "first_column_name" + TEXT_TYPE + COMMA_SEP + "second_column_name" + TEXT_TYPE + ")"; } 

既然你有这个类,你需要找到一种方法来在应用程序启动时立即使用它来创建你的数据库,因为你知道onCreate()只会被调用一次,所以下面的代码只对数据库第一次很重要。制作,把它放在可以打开应用程序的地方。

  CreateDatabase createAllTables = new CreateDatabase(getApplicationContext()); SQLiteDatabase database = createAllTables.getWritableDatabase(); 

这些行将帮助您创建数据库。

在运行这些行之后,您可以在DDMS看到这样的database ,您可以在SQLite BrowserMozilla Sqlit Manager读取它。

在此处输入图像描述

在成功创建数据库之后,您可以使用以下代码用一些数据填充它,我已经将一些值作为示例来显示。

 public class SqliteTestOneActivity extends AppCompatActivity { private Button save_Button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sqlite_test_one); initializeUI(); } private void initializeUI() { save_Button = (Button) findViewById(R.id.SqliteTestOneActivity_button); save_Button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MyReader myReader = new MyReader(getApplicationContext()); myReader.open(); myReader.insert("Jack", "Sam"); myReader.close(); } }); } private static class MyReader { private static final String Table_Name = "TestOne_Table"; private final Context mCtx; private SQLiteDatabase mDb; private InternalHelper mDbHelper; public MyReader(Context mCtx) { this.mCtx = mCtx; } public MyReader open() { this.mDbHelper = new InternalHelper(this.mCtx); this.mDb = mDbHelper.getWritableDatabase(); return this; } public void insert(String first, String second) { ContentValues values = new ContentValues(); values.put("first_column_name", first); values.put("second_column_name", second); mDb.insert(Table_Name, null, values); } public void close() { if (mDbHelper != null) { mDbHelper.close(); } } private static class InternalHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "database_name.sqlite"; private static final int DATABASE_VERSION = 1; public InternalHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } public void onCreate(SQLiteDatabase paramSQLiteDatabase) { } public void onUpgrade(SQLiteDatabase paramSQLiteDatabase, int paramInt1, int paramInt2) { } } } } 

一旦运行此活动,单击“保存”按钮,您的数据将保存在数据库中,您可以从DDMS中提取数据库并检查记录

产量 在此处输入图像描述

您不应该尝试从SQLiteOpenHelper生命周期方法(如onCreate()或从那里调用的方法getReadableDatabase()调用getWritableDatabase()getReadableDatabase() 。 这会因“被称为递归”exception而失败。

而是使用作为onCreate()或其他生命周期方法的参数提供的SQLiteDatabase