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

时间:2016-01-17 02:57:02

标签: java android android-sqlite

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

中打开数据库时,应用程序崩溃

基本上我在创建数据库后尝试填充数据库,但显然没有以正确的方式进行。

来自SQLiteHelper类

...

public class dbContents {


public static void baseContents(Context context) {

    dbDataSource ds = new dbDataSource(context);
    ds.open();

来自内容创建者类

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
}

...

来自dbDataSource类

 A* a = new A[10];
 unsigned int *overhead = reinterpret_cast<int*>(&a[-4]) ;

...

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

2 个答案:

答案 0 :(得分:3)

您不应尝试从getWritableDatabase()生命周期方法(例如getReadableDatabase())或从那里调用的方法调用SQLiteOpenHelperonCreate()。这将失败,并且#34;递归调用&#34;异常。

相反,请使用SQLiteDatabase作为onCreate()或其他生命周期方法的参数。

答案 1 :(得分:1)

我编写了一些代码片段,可以帮助您填充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();

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

运行这些行之后,您可以在database中看到DDMS这样的SQLite Browser,您可以在Mozilla Sqlit Managerpublic 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) { } } } }

enter image description here

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

    global  main
    extern  printf

    section .text
main:
    mov  qword  [VAR_0], 1 ; Init first variable
    mov qword [VAR_1], 2   ; Init second variable
    mov    rdi, format     ; Print first variable -> outputs 2
    mov    rsi, [VAR_0]
    mov    eax, 0
    call   printf
    mov    rdi, format     ; Print second variable -> outputs 2
    mov    rsi, [VAR_1]
    mov    eax, 0
    call   printf


section .bss
VAR_0: resq    0
VAR_1: resq    0


section .data
format db "%d", 10, 0

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

  

输出   enter image description here