为什么在升级sqlite数据库后出现错误“无法读取CursorWindow中的第0行,col -1”

时间:2016-09-27 07:40:21

标签: android sqlite

我在Anroid应用程序中升级DATABASE_VERSION后收到此错误消息。

这是我的SQLiteOpenHelper类

public class ShopDatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "database_name";

private static final int DATABASE_VERSION = 7;

public ShopDatabaseHelper() {
    super(App.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(TagCacheTable.CREATE_TAG_TABLE_SQL);

    db.execSQL(StickerGroupTable.CREATE_TABLE_SQL);

    db.execSQL(StickerTable.CREATE_TABLE_SQL);
    db.execSQL(StickerTable.CREATE_TABLE_INDEX_1);

    db.execSQL(SkinTable.CREATE_TABLE_SQL);
    db.execSQL(SkinTable.CREATE_TABLE_INDEX_1);

    db.execSQL(SkinGroupTable.CREATE_TABLE_SQL);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.d(String.valueOf(oldVersion) + "->" +String.valueOf(newVersion));
    try {
        // 1 -> 2
        if (oldVersion < 2) {
            db.execSQL("DROP TABLE tagtable");
            db.execSQL(TagCacheTable.CREATE_TAG_TABLE_SQL);
            db.execSQL(StickerGroupTable.CREATE_TABLE_SQL);
            db.execSQL(StickerTable.CREATE_TABLE_SQL);
            db.execSQL(StickerTable.CREATE_TABLE_INDEX_1);
        }

        // 2 -> 3
        if (oldVersion < 3) {
            Cursor cursor = db.rawQuery("PRAGMA table_info (" + StickerGroupTable.STICKER_GROUP_TABLE + ")", null);
            if (cursor.getColumnIndex(StickerGroupTable.COL_USER_PRIORITY) == -1) {
                db.execSQL(StickerGroupTable.ADD_USER_PRIORITY_COLUMN_SQL);
            }
            cursor.close();
        }

        // 3 -> 4
        if (oldVersion < 4) {
            db.execSQL(SkinTable.CREATE_TABLE_SQL);
            db.execSQL(SkinTable.CREATE_TABLE_INDEX_1);
            db.execSQL(SkinGroupTable.CREATE_TABLE_SQL);
        }

        // 4 -> 5
        if (oldVersion < 5) {
            Cursor cursor = db.rawQuery("PRAGMA table_info (" + StickerGroupTable.STICKER_GROUP_TABLE + ")", null);
            if (cursor.getColumnIndex(StickerGroupTable.COL_CAMPAIGN_URI) == -1) {
                db.execSQL(StickerGroupTable.ADD_CAMPAIGN_URI_COLUMN_SQL);
            }
            if (cursor.getColumnIndex(StickerGroupTable.COL_CAMPAIGN_APP_PACKAGE) == -1) {
                db.execSQL(StickerGroupTable.ADD_CAMPAIGN_APP_PACKAGE_COLUMN_SQL);
            }
            cursor.close();
            cursor = db.rawQuery("PRAGMA table_info (" + SkinGroupTable.SKIN_GROUP_TABLE + ")", null);
            if (cursor.getColumnIndex(SkinGroupTable.COL_CAMPAIGN_URI) == -1) {
                db.execSQL(SkinGroupTable.ADD_CAMPAIGN_URI_COLUMN_SQL);
            }
            if (cursor.getColumnIndex(SkinGroupTable.COL_CAMPAIGN_APP_PACKAGE) == -1) {
                db.execSQL(SkinGroupTable.ADD_CAMPAIGN_APP_PACKAGE_COLUMN_SQL);
            }
            cursor.close();
        }

        // 5 -> 6
        if(oldVersion < 6) {
            Cursor cursor;
            cursor = db.rawQuery("PRAGMA table_info (" + StickerGroupTable.STICKER_GROUP_TABLE + ")", null);
            if (cursor.getColumnIndex(StickerGroupTable.COL_CAN_DOWNLOAD_FREELY_NEXT) == -1) {
                db.execSQL(StickerGroupTable.ADD_CAN_DOWNLOAD_FREELY_NEXT_COLUMN_SQL);
            }
            cursor.close();
            cursor = db.rawQuery("PRAGMA table_info (" + SkinGroupTable.SKIN_GROUP_TABLE + ")", null);
            if (cursor.getColumnIndex(SkinGroupTable.COL_CAN_DOWNLOAD_FREELY_NEXT) == -1) {
                db.execSQL(SkinGroupTable.ADD_CAN_DOWNLOAD_FREELY_NEXT_COLUMN_SQL);
            }
            cursor.close();
        }
        // 6 -> 7
        if(oldVersion < 7) {
            Cursor cursor;
            cursor = db.rawQuery("PRAGMA table_info (" + StickerGroupTable.STICKER_GROUP_TABLE + ")", null);
            if (cursor.getColumnIndex(StickerGroupTable.COL_EXISTING_IN_XML) == -1) {
                db.execSQL(StickerGroupTable.ADD_EXISTING_IN_XML_COLUMN_SQL);
            }
            cursor.close();
            cursor = db.rawQuery("PRAGMA table_info (" + SkinGroupTable.SKIN_GROUP_TABLE + ")", null);
            if (cursor.getColumnIndex(SkinGroupTable.COL_EXISTING_IN_XML) == -1) {
                db.execSQL(SkinGroupTable.ADD_EXISTING_IN_XML_COLUMN_SQL);
            }
            cursor.close();
        }
    } catch (Exception e){
        Log.e(e);
    }
}
}

当我将DATABASE_VERSION从5升级到6(将新列添加到Sticker表中)时,它工作正常。但是,当版本增加到7(将另一列添加到同一个表 - Sticker表中)时,该错误开始更频繁地发生(对于某些设备而非所有设备)。

有时,我收到了这个错误。

Caused by: android.database.sqlite.SQLiteException: no such table: skin_group (code 1): , while compiling: select * from skin_group limit 0

(当我们通过此方法更改方法以检查列是否存在时会发生这种情况 )

    public boolean checkIfColumnExist(SQLiteDatabase db, String column) {
    Cursor cursor = db.rawQuery("select * from " + SKIN_GROUP_TABLE + " limit 0", null);
    if (cursor.getColumnIndex(column) == -1) {
        return false;
    }
    return true;
}

有时,

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.utagoe.momentdiary/com.utagoe.momentdiary.MomentDiaryVanilla}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2352)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2412)
at android.app.ActivityThread.access$800(ActivityThread.java:149)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1326)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5335)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetLong(Native Method)
at android.database.CursorWindow.getLong(CursorWindow.java:511)
at android.database.CursorWindow.getInt(CursorWindow.java:578)
at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:69)
at {pakagename}.shop.sticker.StickerGroupDao.cursorToGroupList(StickerGroupDao.java:314)
at {pakagename}.shop.sticker.StickerGroupDao.findAll(StickerGroupDao.java:55)
at {pakagename}.shop.ShopItemBizLogic.findAllGroups(ShopItemBizLogic.java:170)
at {pakagename}.database.shop.sticker.StickerTableNormalizer.invalidateItemGroupsGottenPremiumly(StickerTableNormalizer.java:45)
at {pakagename}.database.shop.sticker.StickerTableNormalizer.normalize(StickerTableNormalizer.java:39)
at {pakagename}.afterPermissionGranted(Main.java:184)
at {pakagename}.MomentDiary.dealWithPermission(Main.java:162)
at onCreate(MomentDiary.java:138)
at {pakagename}.MomentDiaryVanilla.onCreate(Main.java:26)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
... 10 more

我一直试图通过

强制进行升级
    public void forceUpdateDatabase() {
    openDatabase();
    db.close();
}

    protected synchronized void openDatabase() {
    if (db == null || !db.isOpen()) {
        db = dbHelper.getWritableDatabase();
    }
}

我的数据库中有几个表,这些表扩展了这个AbstractBizLogic以从这些表中获取数据。

public abstract class AbstractBizLogic {

protected SQLiteDatabase db;

private SQLiteOpenHelper dbHelper;

protected AbstractBizLogic(SQLiteOpenHelper dbHelper) {
    this.dbHelper = dbHelper;
}


public TransactionManager beginTransaction() {
    openDatabase();
    return new TransactionManager(db);
}

protected synchronized void openDatabase() {
    if (db == null || !db.isOpen()) {
        db = dbHelper.getWritableDatabase();
    }
}

public synchronized void closeDatabase() {
    if (db != null && db.isOpen()) {
        db.close();
    }
}
}

这是其中一个类。

public abstract class ShopItemBizLogic<Group extends ItemGroup, Item extends ShopItem> extends
    AbstractBizLogic {

@Inject
private Preferences pref;

protected abstract ShopContext<Group, Item> getShopContext();

protected abstract String getEntryUrl();

public ShopItemBizLogic() {
    super(Injection.getBean(ShopDatabaseHelper.class));
    Injection.inject(this, ShopItemBizLogic.class);
}

public enum ShopInfoStatus {
    SUCCESS, IO_ERROR, NETWORK_DOWN, NEED_UPGRADE_APP, NOT_AVAILABLE, INVALID_XML, UNKNOWN_ERROR
}

public void refreshShopInfoAsync(final Callback<ShopInfoStatus> callback) {

}

public Group findGroup(String groupId) {
    openDatabase();
    return getShopContext().getGroupDao().find(db, groupId);
}

public Item findItem(String itemId) {
    openDatabase();
    return getShopContext().getItemDao().findById(db, itemId);
}

public List<Item> findItems(Group group) {
    openDatabase();
    return getShopContext().getItemDao().findAllByGroup(db, group.getId());
}

public List<Item> findItems(String groupId) {
    openDatabase();
    return getShopContext().getItemDao().findAllByGroup(db, groupId);
}

public List<Group> findAllGroups(boolean availableOnly, OrderBy orderBy) {
    try {
        openDatabase();
        return getShopContext().getGroupDao().findAll(db, ChargeType.All, availableOnly, orderBy, 0);
    } catch (SQLException e) {
        Log.e(e);
    }
    return Collections.emptyList();
}

public boolean insert(Group group, List<Item> products, boolean cleanFirst) {
    Log.d("Insert group:", group.getId(), "clean first =", cleanFirst);
    openDatabase();
    TransactionManager tx = beginTransaction();
    try {
        if (cleanFirst) {
            getShopContext().getItemDao().deleteAll(db, group.getId());
            getShopContext().getGroupDao().delete(db, group);
            getShopContext().getStorageManager().deleteGroup(group);
        }
        getShopContext().getGroupDao().insert(db, group);
        if (products != null) {
            for (Item product : products) {
                getShopContext().getItemDao().insert(db, product);
            }
        }
        tx.commit();
        return true;
    } catch (Exception e) {
        Log.e(e);
        return false;
    } finally {
        tx.endTransaction();
    }
}

public boolean hasBrokenGroup() {
    try {
        openDatabase();
        return getShopContext().getGroupDao().existBroken(db);
    } catch (Exception e) {
        Log.e(e);
    }
    return false;
}

public void insertOrUpdateGroup(Group group, List<Item> items, boolean keepLastUsed) {
    openDatabase();
    TransactionManager tx = beginTransaction();
    try {
        getShopContext().getGroupDao().update(db, group);
        for (Item item : items) {
            if (!getShopContext().getItemDao().existById(db, item.getId())) {
                getShopContext().getItemDao().insert(db, item);
            } else {
                getShopContext().getItemDao().update(db, item, keepLastUsed);
            }
        }
        tx.commit();
    } finally {
        tx.endTransaction();
    }
}

public void updateAllUserPriority(List<Group> groups) {
    openDatabase();
    TransactionManager tx = beginTransaction();
    try {
        for (Group item : groups) {
            getShopContext().getGroupDao().updateUserPriority(db, item);
        }
        tx.commit();
    } catch (Exception e) {
        Log.e(e);
    } finally {
        tx.endTransaction();
    }
}

public void insert(Group group) {
    openDatabase();
    getShopContext().getGroupDao().insert(db, group);
}

public void insertOrUpdate(Group group) {
    openDatabase();
    if (getShopContext().getGroupDao().exist(db, group.getId())) {
        getShopContext().getGroupDao().update(db, group);
    } else {
        getShopContext().getGroupDao().insert(db, group);
    }
}

public void insert(Item product) {
    openDatabase();
    getShopContext().getItemDao().insert(db, product);
}

public void update(Group group) {
    openDatabase();
    getShopContext().getGroupDao().update(db, group);
}

public void update(Item product, boolean keepLastUsed) {
    openDatabase();
    getShopContext().getItemDao().update(db, product, keepLastUsed);
}

public void markAsBroken(Group group) {
    group.setBroken(true);
    Log.w("Mark as Broken:", group.getId());
    try {
        openDatabase();
        getShopContext().getGroupDao().updateBrokenFlag(db, group);
    } catch (Exception e) {
        Log.e(e);
    }
}

public void updateMaxUserPriority(Group group) {
    openDatabase();
    TransactionManager tx = beginTransaction();
    try {
        int maxUserPriority = getShopContext().getGroupDao().findMaxUserPriority(db);
        group.setUserPriority(maxUserPriority);
        getShopContext().getGroupDao().updateUserPriority(db, group);
        tx.commit();
    } finally {
        tx.endTransaction();
    }
}

public void deleteGroup(Group group, boolean deleteFiles) {
    if (deleteFiles) {
        openDatabase();
        TransactionManager tx = beginTransaction();
        try {
            getShopContext().getItemDao().deleteAll(db, group.getId());
            getShopContext().getGroupDao().delete(db, group);
            getShopContext().getStorageManager().deleteGroup(group);
            tx.commit();
        } catch (Exception e) {
            Log.e(e);
        } finally {
            tx.endTransaction();
        }
    } else {
        group.setAvailable(false);
        update(group);
    }
}

public void deleteItems(Group group, boolean deleteFiles) {
    openDatabase();
    TransactionManager tx = beginTransaction();
    try {
        getShopContext().getItemDao().deleteAll(db, group.getId());
        group.setAvailable(false);
        group.setBroken(true);
        getShopContext().getGroupDao().update(db, group);
        if (deleteFiles) getShopContext().getStorageManager().deleteGroup(group);
        tx.commit();
    } catch (Exception e) {
        Log.e(e);
    } finally {
        tx.endTransaction();
    }
}

public List<Group> findAllExternGroups(OrderBy orderBy) {
    try {
        openDatabase();
        return getShopContext().getGroupDao().findAll(db, ChargeType.ExternOnly, false, orderBy, 0);
    } catch (SQLException e) {
        Log.e(e);
    }
    return Collections.emptyList();
}

public LocalDate findLatestReleaseDate() {
    try {
        openDatabase();
        return getShopContext().getGroupDao().findLatestReleaseDate(db);
    } catch (SQLException e) {
        Log.e(e);
    }
    return null;
}

public boolean isAvailable(Group group) {
    openDatabase();
    try {
        boolean b = getShopContext().getGroupDao().isAvailable(db, group.getId());
        group.setAvailable(b);
        return b;
    } catch (Exception e) {
        Log.e(e);
        return false;
    }
}

private void download(Group group) {
    try {
        ShopItemDownloadManager.startDownloadService(App.getContext(), group, true);
    } catch (Exception e) {
        Log.e(e);
    }
}

private List<String> scanV1InstalledStickerGroupNamesFromFileSystem() {
    StickerBizLogic stickerBizLogic = (StickerBizLogic) getShopContext().getBizLogic();
    return stickerBizLogic.scanV1InstalledStickerGroupNamesFromFileSystem();
}

private void deleteStickerV1Directory() {
    StickerBizLogic stickerBizLogic = (StickerBizLogic) getShopContext().getBizLogic();
    stickerBizLogic.deleteV1Directory();
}

private void setupRirakkuma() {
    SkinBizLogic skinBizLogic = (SkinBizLogic) getShopContext().getBizLogic();
    skinBizLogic.initRirakkuma();
}

private void clearExistingInXML(){
    try {
        openDatabase();
        getShopContext().getGroupDao().clearExistingInXML(db);
    } catch (Exception e) {
        Log.e(e);
    }
}

private void updateExistingInXML(String groupId){
    try {
        openDatabase();
        getShopContext().getGroupDao().updateExistingInXML(db, groupId);
    } catch (Exception e) {
        Log.e(e);
    }
}
}

请帮我看看我的sqlite数据库发生了什么。非常感谢你。

0 个答案:

没有答案