在我的应用程序中,我通过 assets 文件夹提供最新版本的数据库。为简单起见,假设我的数据库方案是 PRIM KEY INTEGER _id、TEXT 名称和 INTEGER 数量。数量是用户可以在应用程序中编辑的唯一内容,其他一切都是静态数据。数量默认为 0。
这是我目前正在尝试做的 onUpgrade:
1.) 遍历所有表,找到数量 > 0 的条目,并将这些条目存储在包含 ID 和 Quantity 值以及原始表名称的对象列表中。
2.) 删除我刚刚迭代的旧数据库
3.) 从包含更新的静态信息的资产中复制新数据库。
4.) 遍历步骤 1 中的列表,并使用相应表中的数量更新相应的 ID。
这是我的 onUpdate 方法(titleArray 是一个包含我的表名的字符串数组):
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("TaskDBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion);
ArrayList<backupKey> bak = new ArrayList<backupKey>();
Cursor cursor = null;
for(int i = 0; i < titleArray.length; i++)
{
cursor = db.rawQuery("SELECT * FROM " + titleArray[i] + " WHERE quantity > 0", null);
if (cursor.moveToFirst()){
do{
backupKey key = new backupKey(titleArray[i],
cursor.getInt(cursor.getColumnIndex("_id")),
cursor.getInt(cursor.getColumnIndex("quantity")));
bak.add(key);
}while(cursor.moveToNext());
}
}
cursor.close();
myContext.deleteDatabase(DB_NAME);
try
{
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName, false);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
} catch (IOException e)
{
Log.w("TaskDBAdapter", "failed");
throw new Error("Error copying database");
}
for (int i = 0; i < bak.size(); i++)
{
ContentValues args = new ContentValues();
args.put("quantity", bak.get(i).quantity);
String where = "_id = ?";
String[] whereArgs = {Integer.toString(bak.get(i).id)};
db.update(bak.get(i).range, args, where, whereArgs);
}
} //End of onUpgrade
我可以确认 arraylist 已成功填充正确的数据。我之前试图覆盖数据库,但它似乎从来没有工作过。我必须添加 myContext.deleteDatabase(DB_NAME); 在数据库被成功替换的文件写入操作之前。我可以确认我的最终更新迭代没有生成任何奇怪的数据——它具有正确的表名、id 和数量值。
问题是,在我的 onUpgrade 之后数量没有更新。静态数据更新到我的资产文件夹中包含的最新版本,但数量数据没有更新。这是因为我破坏了最初提供给方法的数据库(在这种情况下是“db”参数)吗?这甚至是参数吗?如何在新数据库中更新数据?
另外:如果有更好的方法来解决这个问题,我会全神贯注=)