2010-11-21 13 views
5

突然、私のアプリケーションが使用しているデータベースが壊れているようです。 私はデータベースの構造を変更しませんでしたが、今日私のデバイスに何回もアプリケーションを再デプロイしました。AndroidのSQLite DBが突然壊れたのはなぜですか?

次の例外がスローされます。

E/Database(14281): CREATE TABLE android_metadata failed err=26 .. 
E/Database(14281): Failed to setLocale() when constructing, closing the database 
E/Database(14281): android.database.sqlite.SQLiteException: file is encrypted or is not a database 
E/Database(14281): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method) 
E/Database(14281): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1848) 
E/Database(14281): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1798) 
E/Database(14281): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:798) 
E/Database(14281): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:857) 
E/Database(14281): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:850) 
E/Database(14281): at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:539) 
E/Database(14281): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193) 
E/Database(14281): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98) 
E/Database(14281): at com.ecs.android.gps.storage.DBAdapter.open(DBAdapter.java:75) 

データベースは、SQLLiteOpenHelperクラスを使用して初期化されます。

public DBAdapter(Context ctx) 
{ 
    this.context = ctx; 
    DBHelper = new DatabaseHelper(context); 
} 

private static class DatabaseHelper extends SQLiteOpenHelper 
{ 
    DatabaseHelper(Context context) 
    { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) 
    { 
     db.execSQL(DATABASE_CREATE); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, 
    int newVersion) 
    { 
     Log.w(TAG, "Upgrading database from version " + oldVersion 
       + " to " 
       + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS location_history"); 
     onCreate(db); 
    } 
} 
  • 私は基本的に各 操作に データベースとカーソルの両方を閉じる/開いています。
  • いくつかの記事では、これが移動するための方法であること 示しますが、 アンドロイドアプリのために、オープン すべての時間をデータベース接続を維持するために多くの意味 をすることはないだろうか?
  • 多くのリソースを に毎回開いたり閉じたりすると想像することができます。
  • がデータベースにアクセスするアクティビティとサービスは複数あります。 (潜在的に同時に)
  • 私は、ログ

で、そこからリストアする方法、これを引き起こしている可能性があり、どのように将来的にはこれを防ぐためにどのような任意のアイデアを、例外を見たことがありませんか? 私はいくつかの並行性の問題(複数のスレッドがデータベースをオープン/クローズしようとする、または読み書きしようとしている)のために例外が発生しているという印象を持っています。私はマルチスレッドのアクセス、ロックなどに関して、SQLiteデータベースが通常のデータベース(mysql - oracle)と同じくらい堅牢であるかどうかわかりません.....

+0

複数のアクチュエイトでデータを共有するためにデータプロバイダを使用しましたか? – Emile

+0

それは私のTO-DOリストにあり、私が理解しているところでは、それはあなたのための配管の多くを行うのでオプションになるかもしれませんが、私は読み書きするテーブルが1つしかありません。私はまた、他のアプリにデータを公開するつもりはありません。私はちょうどそれがどのように壊れて、それを避けることができます(まだSQLiteDatabaseとSQLiteOpenHelperクラスを使用して)を避けることができることを知りたいです – ddewaele

+0

それを修正していない限り、私はさらにrossthebossの答えを調べます。あなたは、データベースにアクセスするサービスとアクティビティがあると述べました。与えられた2つのアクティビティは、同時に安全ではないと仮定することができます(r)。しかし、あなたが言及したサービスは、おそらくアクティビティと同時に実行されるでしょう。私はjavaの専門家ではありませんが、データベースのロックをロック/チェックするのに役立つメソッドがいくつかあると思います。私。すでに開いているか、データベースをロック/ロック解除しています。これにより、競合を回避し、少なくともエラーを捕捉することができます。 – Emile

答えて

0

おそらくデータベースを違法どういうわけか、それは通常、フラグが立てられ、すべてがうまくいく。

+0

私は基本的に各操作のデータベースとカーソルを開閉しています。データベースにアクセスする複数のアクティビティとサービスがあります。しかし、私はログで例外を見たことはありません。 – ddewaele

+0

大きな問題は、ここから回復する簡単な方法がないことです。基本的にはアプリケーションをアンインストールして(データベースを削除させる)、状況をデブロックするために再インストールする必要があります。 – ddewaele

+0

お試しください。 sdk toolsフォルダに行き、シェルツールを実行してみてください。次に、sqlite3を使用してテーブルを探索します。それがうまくいかない場合は、ここからあなたのローカルマシンにコピーして、他のツールで回復することができます。 – Emile

0

Ae sql lite DBファイルは、テキスト形式ではありませんか? DBファイルを解析して再構築できませんでしたか?また、ロケールプロパティは、アンドロイドがあなたのために求めるメタデータテーブルに設定されていません。もしそうなら、そのテーブルを落として手動で作成すると、あなたのDBを回復する可能性があります。

+0

DBファイルを再構築するロジックを実装することは、私がここに実装するような気がしません:) android_metadataは実際には自動的に作成されますが、スタックトレースから判断すると、Androidは既にDBが壊れていると判断し、その時点でデータベースを削除して再作成します(これはAndroidの標準的なSQL動作です)。それは、その再創造の間に失敗することです。私は腐敗に至る間違ったことを理解しようとしています。 – ddewaele

+0

問題を繰り返すことができますか?あなたがアプリを再インストールするたびに。 – Emile

+0

コメントに記載されている再作成は、DBの初期作成(アプリケーションのインストール時)ではなく、Androidが破損したdbファイルを検出したときの再作成を参照しています。それは再現するのが非常に難しい...私は数日間実行しているアプリケーションを持つことができ、突然それがポップアップ。次回は、数時間後にポップアップできます。 – ddewaele