android - SQLite onUpgrade 未调用
问题描述
我正在检查应用程序的更新过程,并且未调用 onUpgrade。我确实知道getWritableDatabase();
或者
getReadableDatabase();
应该执行以便调用 onUpgrade 并且应该增加 DB_VERSION 。
private DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.myContext = context;
}
我已经在模拟器中安装了应用程序的当前发布版本并执行:
pragma user_version;
出于某种原因,它返回0尽管此版本的源代码的 DB 版本是13。在新版本中,我已经将 DB 版本更新为 20 进行测试,安装更新后,使用
adb install -r myapp.apk
的 DB 版本为 20(使用相同pragma user_version;
),但未调用 onUpgrade。
这个过程通常很简单,所以我不确定出了什么问题。
有人知道出了什么问题吗?为什么当前版本的user_version为0,为什么不调用onUpgrade?
这是 DBHelper 类:
public class DBHelper extends SQLiteOpenHelper {
private static String DB_NAME = "db_name.db3";
private SQLiteDatabase myDataBase;
private final Context myContext;
private static DBHelper sInstance;
public static int DB_VERSION = 20;
public static DBHelper getInstance(Context context) {
if (sInstance == null) {
sInstance = new DBHelper(context.getApplicationContext());
}
return sInstance;
}
private DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.myContext = context;
}
public void createDataBase() throws IOException {
try {
boolean dbExist = checkDataBase();
if (dbExist) {
try {
SQLiteDatabase db = this.getWritableDatabase();
} catch (SQLiteException e) {
Crashlytics.logException(e);
}
} else {
SQLiteDatabase db = this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
Crashlytics.logException(e);
}
}
} catch (Exception e) {
Crashlytics.logException(e);
}
}
private boolean checkDataBase() {
boolean checkdb = false;
try {
String myPath = myContext.getFilesDir().getAbsolutePath()
.replace("files", "databases")
+ File.separator + DB_NAME;
File dbfile = new File(myPath);
checkdb = dbfile.exists();
} catch (SQLiteException e) {
Crashlytics.logException(e);
}
return checkdb;
}
public SQLiteDatabase openDataBase() throws SQLException {
String myPath = myContext.getFilesDir().getAbsolutePath()
.replace("files", "databases")
+ File.separator + DB_NAME;
if (myDataBase == null) {
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
} else {
if (myDataBase.isOpen()) {
return myDataBase;
} else {
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
}
return myDataBase;
}
public SQLiteDatabase openDataBaseForWrite() throws SQLException {
String myPath = myContext.getFilesDir().getAbsolutePath()
.replace("files", "databases")
+ File.separator + DB_NAME;
if (myDataBase == null) {
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} else {
if (myDataBase.isOpen()) {
if (myDataBase.isReadOnly()) {
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} else {
return myDataBase;
}
} else {
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
}
return myDataBase;
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//NOT CALLED
}
}
解决方案
在检查了SQLiteOpenHelper 的源代码后,我部分理解了这个问题,并且@slackwars 的假设是正确的。
似乎只有当 user_version != 0 时才会调用 onUpgrade。
if (version != mNewVersion){
...
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
我不确定为什么它是 0,但我已经使用它来创建使用 onCreate 的解决方法并解决此问题。
推荐阅读
- java - 如何使协变消费者工作?
- python - 从 pandas.dataframe 查询数据时 df[:,'column_name'] 和 df['column_name'] 有什么区别
- java - 为什么我无法检索/获取数据库列中的数据
- swift - Crashlytics Swift:将 fatalError() 消息发送到崩溃日志
- r - 从 R 中的 fft() 中提取傅里叶系数
- excel - Excel对选定单元格的常数进行逻辑测试
- vue.js - v-model 不适用于动态单选按钮,vue js
- java - 是否可以对 Spring-WS 端点中的所有请求使用单个 JAXBContext?
- java - 为什么我们在这个类方法中使用同步块?
- xslt-2.0 - 对文字结果元素和元素构造函数方法使用单个命名空间声明