2

Android アプリで暗号化されたSQLCipherデータベースを使用すると、次のエラーが発生しますが、オンとオフのみです。

net.sqlcipher.database.SQLiteException: not an error
    at net.sqlcipher.database.SQLiteDatabase.dbopen(Native Method)
    at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1950)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:900)
    at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:947)
    at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:195)
    at com.android.storage.DatabaseHelper.getReadable(DatabaseHelper.java:99)
    ...

ほとんどの場合、データベースは正常に動作するため、フォルダassets/とフォルダに適切なファイルがあります。libs/ただし、たまにこのエラーが表示されます。私はこれを私の携帯電話で2回見ましたが、それは常に、何時間も非アクティブになった後にアプリを再開した後です(メモリからクリアされた場合、dbでユーザーのoauthトークンをチェックします)。

Application::onCreate() メソッドからのみ "SQLiteDatabase.loadLibs(this)" を呼び出すので、履歴書でこれが呼び出されず、エラーがスローされていると思います。これは可能ですか?その場合、loadLibs をどこで呼び出す必要がありますか? ユーザーは任意のアクティビティでアプリに入ることができ、トークンがメモリにない場合はデータベースにアクセスします。オプションは、各 Activity::onCreate で loadLibs を呼び出すか、データベースを開こうとするたびに呼び出すかのいずれかです。このように複数回呼び出すと、害やパフォーマンスの問題が発生しますか?

4

1 に答える 1

1

SQLiteDatabase.loadLibs(this);を のアプリケーション サブクラスに移動することを検討してくださいnet.sqlcipher.database.SQLiteOpenHelper。その後、サブクラスの静的インスタンスをApplication引数として渡すことができます。次のようなものが例として考えられます。

public class SchemaManager extends net.sqlcipher.database.SQLiteOpenHelper {

  private static SchemaManager instance;

  public static synchronized SchemaManager getInstance() {
    if(instance == null) {
      SQLiteDatabase.loadLibs(YourApplication.getInstance());
      instance = new SchemaManager(…)
    }
    return instance;
  }
}

提供された例外に関して、Java ルーチンは を呼び出す JNI レイヤーを呼び出しsqlite3_open_v2、ソフト ヒープ リミットを設定し、ビジー タイムアウトを設定します。SQLiteDatabaseクラッシュが発生したときにインスタンスを取得しようとするときに、有効なパスと null 以外のパスフレーズを渡していることを確認するために、ローカルでログを追加することをお勧めします。複数回呼び出しSQLiteDatabase.loadLibs(this);てもパフォーマンスに顕著な影響はありません。発生するほとんどの呼び出しは にSystem.loadLibrary(…)マップされRuntime.getRuntime().loadLibrary(…)ます。動的ライブラリがロードされると、後続の呼び出しは無視されます。

于 2013-09-10T13:39:02.253 に答える