我想在我的android模拟器上安装数据库时升级它.我在我的DbHelper中设置了db版本,它继承自SQLiteOpenHelper到+1.
但是,当我的第一个活动加载时,我实例化我的DbHelper,我希望SQLiteOpenHelper调用onUpgrade,因为db版本现在更新了.但它永远不会被称为.我想知道是否有我遗失的东西.DbHelper使用的版本在哪里存储以与新版本进行比较?为什么这不起作用?
我实际上是将数据库从assets文件夹复制到数据文件夹,而不是重新创建模式.
public class DbHelper extends SQLiteOpenHelper {
private static final String TAG = "DbHelper";
static final String DB_NAME = "caddata.sqlite";
static final int DB_VERSION = 4;
private static String DB_PATH = "";
private Context myContext;
private SQLiteDatabase myDataBase;
public DbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.myContext = context;
DB_PATH = "/data/data/"
+ context.getApplicationContext().getPackageName()
+ "/databases/";
}
public DbHelper open() throws SQLException {
myDataBase = getWritableDatabase();
Log.d(TAG, "DbHelper Opening Version: " + this.myDataBase.getVersion());
return this;
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "onCreate called");
try {
createDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if ( newVersion > oldVersion)
{
Log.d(TAG, "New database version exists for upgrade.");
try {
Log.d(TAG, "Copying database...");
copyDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (!dbExist) {
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
openDataBaseForRead();
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY
| SQLiteDatabase.NO_LOCALIZED_COLLATORS);
Log.d(TAG, "db exists");
} catch (SQLiteException e) {
// database does't exist yet.
Log.d(TAG, "db doesn't exist");
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
private void copyDataBase() throws IOException {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[2048];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
myDataBase.setVersion(DB_VERSION);
}
public void openDataBaseForRead() throws SQLException {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
public void openDataBaseForWrite() throws SQLException {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.NO_LOCALIZED_COLLATORS );
}
}
Run Code Online (Sandbox Code Playgroud)
kde*_*iry 29
这是来自以下来源的代码段SQLiteOpenHelper.getWritableDatabase():
int version = db.getVersion();
if (version != mNewVersion) {
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,在调用中调用onCreate()或onUpgrade()调用getWritableDatabase().每当需要实例时,您必须使用这些调用SQLiteDatabase.你不应该使用自己的方法,除非它们是getWritableDatabase或者getReadableDatabase方法的包装器.
我已经解决了问题。仅当您从资产复制数据库时,才会出现此问题。Assets文件夹中的db的默认版本为0。因此,当您使用版本号(例如1)调用数据库打开帮助程序,然后用资产中的那个覆盖它时,版本号将重置为0。
并且,当您调用db.getReadableDatabase()或db.getWriteableDatabase来调用onUpgrade方法时,它会失败,因为版本号0应该是一个全新的数据库。您可以查看SqliteOpenHelper的源代码。仅当版本大于零且当前版本大于旧版本时,它才会触发onUpgrade方法。
`
db.beginTransaction();
try {
//Skips updating in your case
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
Run Code Online (Sandbox Code Playgroud)
`
因此,这就是我为克服此问题所做的工作。它没有完美的解决方案,但是可以正常工作。基本上,在调用SQLiteOpenHelper类的超级方法(数据库管理器的构造函数)之前,需要更新数据库版本。
`
try
{
String myPath = MyApplication.context.getDatabasePath(DATABASE_NAME).toString();
//open a database directly without Sqliteopenhelper
SQLiteDatabase myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
//if the version is default 0 the update the version
if (myDataBase.getVersion() == 0)
{
//update the database version to the previous one
myDataBase.execSQL("PRAGMA user_version = " + 1);
}
//Close DataBase
myDataBase.close();
}
catch (Exception e)
{
//Do Nothing a fresh install happened
}
Run Code Online (Sandbox Code Playgroud)
`
PS:我知道答案来晚了,但是对于像我这样正在寻找特定解决方案的人可能会有所帮助
| 归档时间: |
|
| 查看次数: |
18894 次 |
| 最近记录: |