我想,当它被安装到我的Android模拟器来升级我的数据库。 我已经设置了分贝版本我DbHelper继承于SQLiteOpenHelper +1。
然而,当我第一次活动的负载,我实例我DbHelper,我希望SQLiteOpenHelper打电话onUpgrade为DB版本现已更新。然而,它永远不会被调用。我不知道是否有我丢失的东西。哪里是该DbHelper使用存储比较相对于新版本的版本?这是为什么不工作?
我其实复制数据库从资产文件夹到数据文件夹,而不是重新创建模式。
公共类DbHelper扩展SQLiteOpenHelper {
私有静态最后字符串变量=DbHelper;
静态最后弦乐DB_NAME =caddata.sqlite;
静态最终诠释DB_VERSION = 4;
私有静态字符串DB_PATH =;
私人语境myContext;
私人SQLiteDatabase MyDatabase的;
公共DbHelper(上下文的背景下){
超(背景下,DB_NAME,空,DB_VERSION);
this.myContext =背景;
DB_PATH =/数据/数据/
+ context.getApplicationContext()。getPackageName()
+/数据库/;
}
公共DbHelper的open()抛出的SQLException {
MyDatabase的= getWritableDatabase();
Log.d(TAG,DbHelper开放版本:+ this.myDataBase.getVersion());
回到这一点;
}
@覆盖
市民同步无效的close(){
如果(MyDatabase的!= NULL)
myDataBase.close();
super.close();
}
@覆盖
公共无效的onCreate(SQLiteDatabase DB){
Log.d(TAG的onCreate名为);
尝试 {
的CreateDatabase();
}赶上(IOException异常E){
// TODO自动生成的catch块
e.printStackTrace();
}
}
@覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
如果(动态网页> oldVersion)
{
Log.d(TAG,新的数据库版本存在升级。);
尝试 {
Log.d(TAG,复制数据库......);
copyDataBase();
}赶上(IOException异常E){
// TODO自动生成的catch块
e.printStackTrace();
}
}
}
公共无效的CreateDatabase()抛出IOException异常{
布尔dbExist = checkDataBase();
如果(!dbExist){
尝试 {
copyDataBase();
}赶上(IOException异常E){
抛出新的错误(错误复制数据库);
}
}
openDataBaseForRead();
}
私人布尔checkDataBase(){
SQLiteDatabase CHECKDB = NULL;
尝试 {
字符串mypath中= DB_PATH + DB_NAME;
CHECKDB = SQLiteDatabase.openDatabase(mypath中,空,
SQLiteDatabase.OPEN_READONLY
| SQLiteDatabase.NO_LOCALIZED_COLLATORS);
Log.d(TAG,分贝存在);
}赶上(SQLiteException E){
//数据库的简化版,存在。
Log.d(TAG,分贝不存在);
}
如果(CHECKDB!= NULL){
checkDB.close();
}
返回CHECKDB!= NULL?真假;
}
私人无效copyDataBase()抛出IOException异常{
//打开本地数据库作为输入流
InputStream的myInput = myContext.getAssets()开(DB_NAME)。
//路径刚刚创建的空分贝
字符串outFileName = DB_PATH + DB_NAME;
//打开空分贝的输出流
的OutputStream myOutput =新的FileOutputStream(outFileName);
//传输的字节从inputfile中的OUTPUTFILE
byte []的缓冲区=新的字节[2048];
INT长;
而((长度= myInput.read(缓冲液))大于0){
myOutput.write(缓冲液,0,长度);
}
//关闭流
myOutput.flush();
myOutput.close();
myInput.close();
myDataBase.setVersion(DB_VERSION);
}
公共无效openDataBaseForRead()抛出的SQLException {
//打开数据库
字符串mypath中= DB_PATH + DB_NAME;
MyDatabase的= SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY);
}
公共无效openDataBaseForWrite()抛出的SQLException {
//打开数据库
字符串mypath中= DB_PATH + DB_NAME;
MyDatabase的= SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
}
}
解决方案
这是从 SQLiteOpenHelper.getWritableDatabase源()
A code片断:
INT版本= db.getVersion();
如果(版本!= mNewVersion){
db.beginTransaction();
尝试 {
如果(版本== 0){
的onCreate(DB);
} 其他 {
如果(版本> mNewVersion){
onDowngrade(DB,版本,mNewVersion);
} 其他 {
onUpgrade(DB,版本,mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} 最后 {
db.endTransaction();
}
}
的OnOpen(DB);
正如你所看到的,的onCreate()
或 onUpgrade()
呼叫中被称为 getWritableDatabase()
。
你当你需要 SQLiteDatabase
的实例使用这些调用。你不应该用你自己的方法,除非它们是包装约于 getWritableDatabase
或 getReadableDatabase
方法。
I want to upgrade my database when it is installed onto my android emulator. I have set the db version in my DbHelper which inherits from SQLiteOpenHelper to +1.
However, when my 1st activity loads, I instantiate my DbHelper, which I would expect SQLiteOpenHelper to call onUpgrade as the db version is now newer. However it is never called. I'm wondering if there is something I am missing. Where is the version that the DbHelper is using stored to compare against the new version? Why is this not working?
I am actually copying the database from the assets folder into the data folder rather than re-creating the schema.
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 );
}
}
解决方案
This is a code snippet from the source of 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);
As you can see, the onCreate()
or onUpgrade()
are called within the call to getWritableDatabase()
.
You have to use these calls whenever you need an instance of SQLiteDatabase
. You shouldn't use your own methods, except if they are wrappers arround the getWritableDatabase
or getReadableDatabase
method.