当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类调用它时崩溃。这是一个线程问题吗?
答案 0 :(得分:3)
您不应尝试从getWritableDatabase()
生命周期方法(例如getReadableDatabase()
)或从那里调用的方法调用SQLiteOpenHelper
或onCreate()
。这将失败,并且#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 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) {
}
}
}
}
{ p>
成功创建数据库后,您可以使用以下代码用一些数据填充它,我已经将一些值作为示例来显示。
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中提取数据库并检查记录