我试图创建一个DataBase,在这里我需要创建DataBase,而打开应用程序时不会被任何Onclick方法触发。我真的需要帮忙吗?
我试图通过主类onCreate调用它,但它退出了应用程序。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DataBaseHelper dbh = new DataBaseHelper(MainActivity.this);
dbh.onCreate();
}发布于 2022-11-25 21:08:11
简而言之,您不会尝试调用onCreate方法。这样做,就像您已经做过的那样,当数据库实际上还没有创建时,就会调用它,因此可能会得到一个空指针异常。
更具体地说,当您实例化DataBaseHelper时,它实际上并不创建数据库,它只在尝试访问数据库并且调用getWritableDatabase或getReadableDatabase时才这样做,在这种情况下,数据库将被打开。
getReadableDatabase将获得一个可写数据库。不同之处在于,在某些罕见的情况下,getReadableDatabase可能返回只能读取的数据库。根据- This will be the same object returned by getWritableDatabase() unless some problem, such as a full disk, requires the database to be opened read-only. In that case, a read-only database object will be returned.- [https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper#getReadableDatabase()](https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper#getReadableDatabase(%29)如果在打开数据库的过程中,数据库不存在,那么在创建数据库之后,onCreate方法被称为,而传递给onCreate方法的SQLiteDatabase是一个现有的数据库。然后,onCreate方法允许将表、索引、视图、触发器添加到数据库中。
创建数据库时(在调用数据库之前,它将有两个表sqlite_master (模式)和android_metadata (存储设备的区域设置),这些是系统表)。
A FIX
不要调用SQLiteOpenHelper方法,而是让onCreate方法在需要时调用onCreate方法。
您可以使用getWritableDatabase()或getReadableDatabase()强制这样做,而无需执行任何其他操作。你可以:-
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DataBaseHelper dbh = new DataBaseHelper(MainActivity.this); /* NOTE only instantiates the helper, it does not create the database */
//dbh.onCreate(); /*<<<<<<<<<< COMMENTED OUT */
SQLiteDatabase db = dbh.getWritableDatabase(); /*<<<<<<<<<< ADDED to force an open and if need be the one-time creation of the database*/
}Demonstration
下面是演示上述内容的示例。DataBaseHelper是:-
class DataBaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_FILENAME = "the_database.db";
public static final int DATABASE_VERSION_NUMBER = 1;
DataBaseHelper(Context context) {
super(context,DATABASE_FILENAME,null,DATABASE_VERSION_NUMBER);
}
/*
NOTE onCreate is only called when an attempt is made to get a writable/readable SQLiteDatabase
in which case the database is create by the SQLiteOpenHelper.
If the database already exists then it will not be called. As such onCreate is called only
once for the lifetime of the database.
*/
@Override
public void onCreate(SQLiteDatabase db) {
/* Demonstrate the database components BEFORE creating any user defined components */
/* YOU WOULD NOT TYPICALLY DO THIS */
Cursor csr = db.query("sqlite_master",null,null,null,null,null,null);
DatabaseUtils.dumpCursor(csr);
csr.close();
/* Create the user components */
db.execSQL("CREATE TABLE IF NOT EXISTS the_table (id INTEGER PRIMARY KEY, col1 TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public boolean doesDBExist(Context context, String tagExtra) {
String TAG = "DBDEBUG" + tagExtra;
String path = context.getDatabasePath(this.getDatabaseName()).getPath();
boolean rv = false;
if (context.getDatabasePath(this.getDatabaseName()).exists()) {
rv = true;
Log.d(TAG,"The database " + this.getDatabaseName() + " exists. It is located at " + path);
} else {
StringBuilder sb = new StringBuilder( "\n\tThe databases folder " + context.getDatabasePath(this.getDatabaseName()).getParentFile().getPath());
rv = false;
if (context.getDatabasePath(this.getDatabaseName()).getParentFile().exists()) {
sb.append(" exists.");
} else {
sb.append(" does not exist.");
}
Log.d(TAG,"The database " + this.getDatabaseName() + " does not exist as location " + path + sb.toString());
}
return rv;
}
}也就是一个基本的类,它扩展了SQLiteOpenhelper以外的
doesDBExist方法,记录结果。在创建单个表之前,onCreate方法从sqlite_master表(数据库模式)中提取现有组件。所使用的活动代码与您的类似,但是有更多的方法调用/代码来记录信息。:-
public class MainActivity extends AppCompatActivity {
DataBaseHelper dbh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbh = new DataBaseHelper(this);
dbh.doesDBExist(this,"STG01"); /* before opening the database see if it exists */
SQLiteDatabase db = dbh.getWritableDatabase(); /* should open and create db if required */
dbh.doesDBExist(this,"STG02"); /* should now exist */
Cursor csr = db.query("sqlite_master",null,null,null,null,null,null);
DatabaseUtils.dumpCursor(csr);
csr.close();
}
}结果
当作为新安装运行时,日志包含:-
2022-11-26 09:01:25.121 D/DBDEBUGSTG01: The database the_database.db does not exist as location /data/user/0/a.a.so74564168sqliteoncreatedemo/databases/the_database.db
The databases folder /data/user/0/a.a.so74564168sqliteoncreatedemo/databases exists.
2022-11-26 09:01:25.151 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@cf2ef01
2022-11-26 09:01:25.151 I/System.out: 0 {
2022-11-26 09:01:25.151 I/System.out: type=table
2022-11-26 09:01:25.152 I/System.out: name=android_metadata
2022-11-26 09:01:25.152 I/System.out: tbl_name=android_metadata
2022-11-26 09:01:25.152 I/System.out: rootpage=3
2022-11-26 09:01:25.152 I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
2022-11-26 09:01:25.153 I/System.out: }
2022-11-26 09:01:25.153 I/System.out: <<<<<
2022-11-26 09:01:25.162 D/DBDEBUGSTG02: The database the_database.db exists. It is located at /data/user/0/a.a.so74564168sqliteoncreatedemo/databases/the_database.db
2022-11-26 09:01:25.163 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@40841a6
2022-11-26 09:01:25.163 I/System.out: 0 {
2022-11-26 09:01:25.164 I/System.out: type=table
2022-11-26 09:01:25.164 I/System.out: name=android_metadata
2022-11-26 09:01:25.164 I/System.out: tbl_name=android_metadata
2022-11-26 09:01:25.164 I/System.out: rootpage=3
2022-11-26 09:01:25.164 I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
2022-11-26 09:01:25.164 I/System.out: }
2022-11-26 09:01:25.164 I/System.out: 1 {
2022-11-26 09:01:25.165 I/System.out: type=table
2022-11-26 09:01:25.165 I/System.out: name=the_table
2022-11-26 09:01:25.165 I/System.out: tbl_name=the_table
2022-11-26 09:01:25.165 I/System.out: rootpage=4
2022-11-26 09:01:25.165 I/System.out: sql=CREATE TABLE the_table (id INTEGER PRIMARY KEY, col1 TEXT)
2022-11-26 09:01:25.165 I/System.out: }
2022-11-26 09:01:25.166 I/System.out: <<<<<因此,在实例化
当调用android_metadata方法时,按照第二个集合,onCreate方法被自动调用,模式被转储,唯一存在的表是
- android\_metadata is a table unique to android and embedded SQLite API, it stores the locale enabling it's management from the SQLite perspective.doesDBExist的第二个调用现在显示该文件确实存在。最后,从
onCreate方法.创建。
后续运行
如果应用程序再次运行,则日志包含:-
2022-11-26 09:22:58.583 D/DBDEBUGSTG01: The database the_database.db exists. It is located at /data/user/0/a.a.so74564168sqliteoncreatedemo/databases/the_database.db
2022-11-26 09:22:58.587 D/DBDEBUGSTG02: The database the_database.db exists. It is located at /data/user/0/a.a.so74564168sqliteoncreatedemo/databases/the_database.db
2022-11-26 09:22:58.587 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@9c8df94
2022-11-26 09:22:58.587 I/System.out: 0 {
2022-11-26 09:22:58.588 I/System.out: type=table
2022-11-26 09:22:58.588 I/System.out: name=android_metadata
2022-11-26 09:22:58.588 I/System.out: tbl_name=android_metadata
2022-11-26 09:22:58.588 I/System.out: rootpage=3
2022-11-26 09:22:58.588 I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
2022-11-26 09:22:58.588 I/System.out: }
2022-11-26 09:22:58.588 I/System.out: 1 {
2022-11-26 09:22:58.588 I/System.out: type=table
2022-11-26 09:22:58.588 I/System.out: name=the_table
2022-11-26 09:22:58.588 I/System.out: tbl_name=the_table
2022-11-26 09:22:58.588 I/System.out: rootpage=4
2022-11-26 09:22:58.588 I/System.out: sql=CREATE TABLE the_table (id INTEGER PRIMARY KEY, col1 TEXT)
2022-11-26 09:22:58.588 I/System.out: }
2022-11-26 09:22:58.588 I/System.out: <<<<<即数据库已存在并已保留/保存。没有调用onCreate (因为现在存在数据库),而且存在表。
https://stackoverflow.com/questions/74564168
复制相似问题