【问题标题】:Android error with sqlcipher on version android 4.2.2android 4.2.2 版本上的 sqlcipher 出现 Android 错误
【发布时间】:2013-08-06 09:15:51
【问题描述】:

当我尝试在 Android 4.2.2 上启动我的项目时遇到问题。 这是堆栈跟踪:

08-06 11:00:50.041: E/AndroidRuntime(10606): Caused by: net.sqlcipher.database.SQLiteException: not an error
08-06 11:00:50.041: E/AndroidRuntime(10606):    at net.sqlcipher.database.SQLiteDatabase.dbopen(Native Method)
08-06 11:00:50.041: E/AndroidRuntime(10606):    at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1951)
08-06 11:00:50.041: E/AndroidRuntime(10606):    at de.greenrobot.dao.wrapper.SQLiteDatabaseWrapper.<init>(SQLiteDatabaseWrapper.java:61)
08-06 11:00:50.041: E/AndroidRuntime(10606):    at de.greenrobot.dao.wrapper.SQLiteDatabaseWrapper.openDatabase(SQLiteDatabaseWrapper.java:224)
08-06 11:00:50.041: E/AndroidRuntime(10606):    at de.greenrobot.dao.wrapper.SQLiteDatabaseWrapper.openOrCreateDatabase(SQLiteDatabaseWrapper.java:276)
08-06 11:00:50.041: E/AndroidRuntime(10606):    at de.greenrobot.dao.wrapper.SQLiteOpenHelperWrapper.getWritableDatabase(SQLiteOpenHelperWrapper.java:95)
08-06 11:00:50.041: E/AndroidRuntime(10606):    at com.e_i.bad.utils.DAOManager.DAOInit(DAOManager.java:62)

这在 Android 4.0.4 上运行良好,但是当我在 Android 4.2 上启动时,所有时间都会崩溃,但出现该异常。我在官方网站上给出了 sqlcipher 的来源,我希望这是我使用的最后一个来源(名称是 SQLCipher+for+android+2.2.0),我没有看到这个项目的最新版本。

提前感谢您的回答(我希望这不是重复问题导致我搜索但未找到答案...)

编辑: 来源:

helper = new DaoMaster.DevOpenHelper(getContext(), id, password, null);
            db = helper.getWritableDatabase();
            daoMaster = new DaoMaster(db);
            daoSession = daoMaster.newSession();

public static class DevOpenHelper extends OpenHelper {

    public DevOpenHelper(Context context, String name, String password, CursorFactory factory) {
        super(context, name, password, factory);
    }

    @Override
    public void onUpgrade(SQLiteDatabaseWrapper db, int oldVersion, int newVersion) {
        dropAllTables(db, true);
        onCreate(db);
    }
}

public static abstract class OpenHelper extends SQLiteOpenHelperWrapper {

    public OpenHelper(Context context, String name, String password, CursorFactory factory) {
        super(context, name, password, factory, SCHEMA_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabaseWrapper db) {
        createAllTables(db, false);
    }
}

public synchronized SQLiteDatabaseWrapper getWritableDatabase() {
    if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
        return mDatabase; // The database is already open for business
    }

    if (mIsInitializing) {
        throw new IllegalStateException("getWritableDatabase called recursively");
    }

    // If we have a read-only database open, someone could be using it
    // (though they shouldn't), which would cause a lock to be held on
    // the file, and our attempts to open the database read-write would
    // fail waiting for the file lock. To prevent that, we acquire the
    // lock on the read-only database, which shuts out other users.

    boolean success = false;
    SQLiteDatabaseWrapper db = null;
    if (mDatabase != null)
        mDatabase.lock();
    try {
        mIsInitializing = true;
        if (mName == null) {
            db = SQLiteDatabaseWrapper.create(null, mPassword);
        } else {
            String path = mContext.getDatabasePath(mName).getPath();

            File dbPathFile = new File(path);
            if (!dbPathFile.exists())
                dbPathFile.getParentFile().mkdirs();

            db = SQLiteDatabaseWrapper.openOrCreateDatabase(path, mPassword, mFactory);
        }

        int version = db.getVersion();
        if (version != mNewVersion) {
            db.beginTransaction();
            try {
                if (version == 0) {
                    onCreate(db);
                } else {
                    if (version > mNewVersion) {
                        Log.w(TAG, "Can't downgrade read-only database from version " + version + " to " + mNewVersion + ": " + db.getPath());
                    }
                    onUpgrade(db, version, mNewVersion);
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }

        onOpen(db);
        success = true;
        return db;
    } finally {
        mIsInitializing = false;
        if (success) {
            if (mDatabase != null) {
                try {
                    mDatabase.close();
                } catch (Exception e) {
                }
                mDatabase.unlock();
            }
            mDatabase = db;
        } else {
            if (mDatabase != null)
                mDatabase.unlock();
            if (db != null)
                db.close();
        }
    }
}

public SQLiteOpenHelperWrapper(Context context, String name, String password, CursorFactory factory, int version) {
    if (version < 1)
        throw new IllegalArgumentException("Version must be >= 1, was " + version);

    mContext = context;
    mName = name;
    mPassword = password;
    mFactory = factory;
    mNewVersion = version;

    if (mPassword != null && mPassword.length() > 0) {
        // Load SQLcipher libraries if needed
        SQLiteDatabaseWrapper.loadLibs(mContext);
    }
}

编辑 2:

SQLiteDatabase.loadLibs(getContext());
        String path = "";
        try {
            path = getContext().getDatabasePath(pathDB + ".db").getPath();
        } catch (NullPreferencesException e) {

        }
        File dbPathFile = new File(path);
        if (!dbPathFile.exists()) {
            dbPathFile.getParentFile().mkdirs();
        }
        SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(path, "123456", null);
        db = new SQLiteDatabaseWrapper(database);

        daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();

【问题讨论】:

  • 尝试升级到 SQLCipher for Android 2.2.1。
  • 我试过了,但这让我遇到了与具有相同堆栈的版本 2.2.0 相同的错误。如果能帮助你理解,我可以给出部分代码。
  • 在此处发布一些源代码,或者创建一个可重现的测试用例。
  • 通过我的编辑,您拥有我认为代码通过的所有状态。如果您需要更多信息,请告诉我,非常感谢您的考虑和您在该问题上的帮助,我很感激。
  • 这看起来非常复杂,没有明显的好处。

标签: java android android-4.0-ice-cream-sandwich android-4.2-jelly-bean sqlcipher


【解决方案1】:

终于成功了。为此,我只需用 greenDao 将所有导入库 android.database 替换为 net.sqlcipher 然后我在 .jar 中导出这个新的 greenDao 我使用 SQLCipher.jar 不要忘记导入 commons-codec.jar 和 guavra-r09.jar 加来自 SQLCipher 的文件夹 armeabi 和文件夹 x86 以及文件夹 assets 中的文件 icudt46l.zip。

在我的情况下,我有一个项目 daocore,其中包含 SQLCipher 并且是依赖项,而我的项目 Android 依赖于该 daocore 项目,该项目在 Android 4.1 及以下版本中工作,但在 4.2 及以上版本中没有,所以问题是项目之间的依赖关系,我不知道为什么,但如果你在源项目中导入所有内容,那么它在所有 Android 中都可以工作。

【讨论】:

    猜你喜欢
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    相关资源
    最近更新 更多