Android 升级数据库后发生SQLiteDatabaseCorruptException

Android 升级数据库后发生SQLiteDatabaseCorruptException,android,android-sqlite,Android,Android Sqlite,我已经升级了我的数据库,它可以在一些手机上完美运行。然而,在其他情况下,我得到SQLiteDatabaseCorruptException 我已经将android_元数据表包含在我的数据库中 我没有为此更新更改应用程序的任何其他部分。因此,查询应该没有问题 我使用SQLite专家创建数据库 错误报告: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.quant.aptitude/com.quant.

我已经升级了我的数据库,它可以在一些手机上完美运行。然而,在其他情况下,我得到SQLiteDatabaseCorruptException

  • 我已经将android_元数据表包含在我的数据库中
  • 我没有为此更新更改应用程序的任何其他部分。因此,查询应该没有问题
  • 我使用SQLite专家创建数据库
错误报告:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.quant.aptitude/com.quant.aptitude.QuestionsActivity}: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed (code 11)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed (code 11)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:838)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:196)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:236)
at com.quant.aptitude.l.a(Unknown Source)
at com.quant.aptitude.QuestionsActivity.a(Unknown Source)
at com.quant.aptitude.QuestionsActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
... 11 more
用于创建和升级数据库的代码

public void createDataBase() throws IOException 
{ 
    boolean mDataBaseExist = checkDataBase();
    if(mDataBaseExist)
    {
        this.getWritableDatabase();
    }
    mDataBaseExist = checkDataBase();


    if(!mDataBaseExist) 
    { 
        this.getReadableDatabase(); 
        this.close(); 
        try  
        { 
            //Copy the database from assets 
            copyDataBase(); 
        }  
        catch (IOException mIOException)  
        { 
            throw new Error("ErrorCopyingDataBase"); 
        } 
    } 
} 

private boolean checkDataBase() 
{ 
    File dbFile = new File(DB_PATH + DB_NAME); 
    return dbFile.exists(); 
} 

private void copyDataBase() throws IOException 
{ 
    InputStream mInput = mContext.getAssets().open(DB_NAME); 
    String outFileName = DB_PATH + DB_NAME; 
    OutputStream mOutput = new FileOutputStream(outFileName); 
    byte[] mBuffer = new byte[1024]; 
    int mLength; 
    while ((mLength = mInput.read(mBuffer))>0) 
    { 
        mOutput.write(mBuffer, 0, mLength); 
    } 
    mOutput.flush(); 
    mOutput.close(); 
    mInput.close(); 
} 

public boolean openDataBase() throws SQLException 
{ 
    String mPath = DB_PATH + DB_NAME; 
    mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
    return mDataBase != null; 
} 

@Override 
public synchronized void close()  
{ 
    if(mDataBase != null) 
        mDataBase.close(); 
    super.close(); 
}

@Override
public void onCreate(SQLiteDatabase arg0) {
    // TODO Auto-generated method stub
}

@Override  
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
    if (oldVersion < newVersion) {  
        try { 
            copyDataBase(); 
        } catch (IOException e) { 
            throw new Error("Error upgrading database"); 
        } 
    } 
}  
public void createDataBase()引发IOException
{ 
布尔值mDataBaseExist=checkDataBase();
if(mDataBaseExist)
{
这是.getWritableDatabase();
}
mDataBaseExist=checkDataBase();
如果(!mDataBaseExist)
{ 
这是.getReadableDatabase();
这个。关闭();
尝试
{ 
//从资产中复制数据库
copyDataBase();
}  
捕获(IOException-mIOException)
{ 
抛出新错误(“ErrorCopyingDataBase”);
} 
} 
} 
私有布尔校验数据库()
{ 
File dbFile=新文件(DB_路径+DB_名称);
返回dbFile.exists();
} 
私有void copyDataBase()引发IOException
{ 
InputStream mInput=mContext.getAssets().open(DB_NAME);
字符串outFileName=DB_路径+DB_名称;
OutputStream mOutput=新文件OutputStream(outFileName);
字节[]mBuffer=新字节[1024];
整数长度;
而((mlLength=mInput.read(mBuffer))>0)
{ 
mOutput.write(mBuffer,0,最大长度);
} 
mOutput.flush();
mOutput.close();
mInput.close();
} 
公共布尔值openDataBase()引发SQLException
{ 
字符串mPath=DB\u路径+DB\u名称;
mDataBase=SQLiteDatabase.openDatabase(mPath,null,SQLiteDatabase.CREATE,如果需要);
返回mDataBase!=null;
} 
@凌驾
公共同步作废关闭()
{ 
if(mDataBase!=null)
mDataBase.close();
super.close();
}
@凌驾
创建公共void(SQLiteDatabase arg0){
//TODO自动生成的方法存根
}
@凌驾
public void onUpgrade(SQLiteDatabase db,intoldversion,intnewversion){
如果(旧版本<新版本){
试试{
copyDataBase();
}捕获(IOE){
抛出新错误(“升级数据库时出错”);
} 
} 
}  

OnUpgrade方法中是否有错误?

我相信您仍然需要添加SQL命令来在onCreate中创建空表,即使您计划覆盖它。Android在为这样的数据库播种时对模式不匹配非常挑剔。你的数据库被复制了吗(在复制数据库之后,你能在SD中看到它吗)?如果文件夹路径不存在,它将无法复制,因为onCreate为空,因此可能无法创建该文件夹路径。

数据库将被复制。升级后的第一次,我得到了错误。下次我打开应用程序时,它工作正常。请看以下答案: