[英]Android SQLite, onCreate() not being called
我一直在努力在我的Android應用程序中創建一個SQLite數據庫。 我看了很多教程,還有很多關於堆棧溢出和其他站點的問題。
這是我的DatabaseHelper類
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
public SQLiteDatabase db;
public static final String DATABASE_NAME = "user.db";
//Module table
public static final String MODULE_TABLE = "modules_table";
public static final String MODULE_COL_1 = "ID";
public static final String MODULE_COL_2 = "CODE";
public static final String MODULE_COL_3 = "TITLE";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
Log.d("SQL", "SQLite dbhelper");
db = getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
//db.execSQL("create table " + MODULE_TABLE + "(" + MODULE_COL_1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " + MODULE_COL_2 + " TEXT, " + MODULE_COL_3 + " TEXT " +")");
db.execSQL("create table modules_table (ID INTEGER PRIMARY KEY
AUTOINCREMENT, CODE TEXT, TITLE TEXT)");
Log.d("SQL", "SQLite onCreate");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + MODULE_TABLE);
onCreate(db);
}
}
我已經設法讓SQLite dbhelper出現在logcat中,但是無法讓SQLite onCreate出現,並且無法在文件資源管理器或設備本身的任何地方找到數據庫,無論是模擬設備還是真實設備。
任何幫助將不勝感激,並為代碼的格式化道歉!
我建議在活動中使用以下( 暫時 ): -
DatabaseHelper myDBHelper = new DatabaseHelper(this); //<<<<<<<<< you appear to already have the equivalent of this line (if so use whatever variable name you have given to the DatabaseHelper object)
Cursor csr = myDBHelper.getWritableDatabase().query("sqlite_master",null,null,null,null,null,null);
DatabaseUtils.dumpCursor(csr);
csr.close();
運行,然后檢查日志。 您應該看到modules_table和sqlite_sequence的輸出(后者因為您已編碼自動增量。
sqlite_master是一個存儲系統信息的系統表,例如表和索引名稱,即模式。
在未植根的設備上,每個應用程序數據(數據/數據)都受到保護,因此您將無法看到數據庫文件。
在模擬器上,它取決於模擬器。 我相信Android工作室的更高版本現在允許訪問,例如: -
請注意,上面是Android 10.1 Pie(API 28),因此數據庫具有預寫日志記錄(WAL),因此-shm和-wal文件也存在。
包是mjt.pvcheck。 完整路徑是data / data / mjt.pvcheck / databases。
我不喜歡使用SQL查詢
db.execSQL("create table modules_table (ID INTEGER PRIMARY KEY
AUTOINCREMENT, CODE TEXT, TITLE TEXT)");
Log.d("SQL", "SQLite onCreate");
相反,我正在使用我自己的SQLiteOpenHelper類實現
import android.content.Context;
import android.content.res.AssetManager;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.zip.GZIPOutputStream;
public class DbProvider extends SQLiteOpenHelper {
private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock(true);
private static final int VERSION = 0;
private final String DB_NAME = "mydb";
private final AssetManager assets;
private DbProvider(Context context) {
super(context, DB_NAME, null, VERSION);
assets = context.getAssets();
}
@NonNull
public static DbProvider getInstance() {
return new DbProvider(App.getContext());
}
@NonNull
public static ReentrantReadWriteLock.WriteLock writeLock() {
return LOCK.writeLock();
}
@NonNull
public static ReentrantReadWriteLock.ReadLock readLock() {
return LOCK.readLock();
}
@NonNull
public static ReentrantReadWriteLock getLock() {
return LOCK;
}
public static void close(DbProvider instance) {
try {
instance.close();
} catch (Exception ex) {
}
}
@Override
public void onCreate(SQLiteDatabase db) {
executeQuery(db, "db-scripts/database.sql", false);
Log.w("database", "database create");
executeQuery(db, "db-scripts/database_updates.sql", true);
Log.w("database", "database update");
}
private void executeQuery(SQLiteDatabase db, String sql, boolean shouldHandleExceptions) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(assets.open(sql)));
String line;
File tempDbScript = new File(Environment.getExternalStorageDirectory(), "iErunt/dbBackup");
tempDbScript.getParentFile().mkdirs();
tempDbScript.createNewFile();
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(tempDbScript));
while ((line = bufferedReader.readLine()) != null) {
line = line.replaceAll("\t+", " ").replaceAll("\n+", " ").replaceAll(" +", " ").replaceAll(";", ";\n");
if (line.startsWith("--") || line.isEmpty()) {
continue;
}
bufferedWriter.write(line);
bufferedWriter.flush();
}
bufferedWriter.close();
bufferedReader.close();
bufferedReader = new BufferedReader(new FileReader(tempDbScript));
db.beginTransaction();
while ((line = bufferedReader.readLine()) != null) {
if (!(line = line.trim().replace(";", "")).isEmpty()) {
if (shouldHandleExceptions) {
try {
db.execSQL(line);
} catch (SQLException ex) {
Log.e("database", ex.getMessage(), ex);
}
} else {
db.execSQL(line);
}
}
}
db.setTransactionSuccessful();
db.endTransaction();
tempDbScript.delete();
} catch (IOException ex) {
Log.e("database", ex.getMessage(), ex);
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
}
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
executeQuery(db, "db-scripts/database_updates.sql", true);
}
}
並將數據庫的初始數據庫模式放在assets/db-scripts/database.sql
,無論何時進行數據庫修改,都要將您的alter查詢放在assets/db-scripts/database_updates.sql
。 更新數據庫時,請務必增加數據庫的VERSION
。
這個類的作用是讀取整個SQL腳本並逐個執行 。 這顯着縮短了開發時間 。
注意:您需要android.permission.WRITE_EXTERNAL_STORAGE
權限,因為這會創建一個臨時文件並在最后刪除它
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.