11

これは私を数日間夢中にさせてきました。私はかなり複雑なAndroidアプリケーションを持っています。複数のスレッドを使用してサーバーからデータをプルし、SQLiteデータベースにデータを入力します。SQLiteOpenHelperの拡張機能を参照するためにシングルトンを使用しています。それぞれのアクティビティでデータベースを開いたり閉じたりしています。

このエラーは、私が4アクティビティの深さで、バックアウトしようとした場合にのみ発生します。データベースを開いたり閉じたりするさまざまな方法を試しました。たとえば、closeをonDestroy()からonPause()メソッドに移動したり、別のopenをonResume()に追加したりしました。

また、私のアクティビティではListViewsとExpandableListViewsを多用しているため、次の記事に基づいてデータベースが閉じられる可能性があることを理解しています。http: //darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed- automatically.html

コードを確認し、すべてのカーソルを閉じるか、アダプターに割り当てられている場合はstartManagingCursor()を呼び出していることを確認しました。

誰かが何が起こっているのかについての手がかりを持っていますか?

java.lang.RuntimeException: Unable to resume activity {com.fieldone/com.fieldone.DispatchActivity}: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3347)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3362)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2162)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:144)
    at android.app.ActivityThread.main(ActivityThread.java:4937)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed
    at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:237)
    at android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:145)
    at android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:567)
    at android.app.Activity.performRestart(Activity.java:3836)
    at android.app.Activity.performResume(Activity.java:3857)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3337)
    ... 10 more

更新: 問題を修正しましたが、なぜこれが修正されたのかわかりません。だから、多分そこにいる誰かが知っているか、説明することができます。

アクティビティのスタックの4番目のアクティビティにいるとき、db.close()を介してdbを閉じようとしていました。これをどこに置いても、必要なデータを取得した後のonCreate、またはonStopまたはonDestroyで、このエラーが発生します。データベースを閉じない場合、問題は発生していません。そのため、何かが原因でデータベースが自動的に閉じています。奇妙なことに、この最後のアクティビティではexpandableListViewを使用していますが、cursorAdapterは使用していません。誰か考えがありますか?これを理解したいと思います。

4

3 に答える 3

20

この質問はかなりの注目を集めているので、私はそれに答えて、私が学んだことと、私の大規模なデータベース駆動型アプリケーションでこの問題を修正するために何がうまくいったかを説明したいと思いました。

  1. 管理カーソルは使用しないでください。それらが非推奨になるのには理由があります。彼らは完全に問題があります。現実的には、とにかく管理カーソルを実際に使用する必要があるシナリオはほとんどありません。代わりに、クエリを実行して、オブジェクトに結果を入力します。複数の行をクエリする場合は、オブジェクトのArrayList <>を作成して、すべての行を保持します。私が今していることは、クエリを実行し、戻り値のカーソルではなく、ArrayList<>を返す関数を作成することです。関数内でカーソルを閉じると完了です。ListViewsの場合、SimpleCursorAdapterを使用できなくなります。これらすべてをBaseAdapterに変換し、ArrayList<>オブジェクトを使用してデータを設定するだけです。

  2. すべてのカーソルを閉じることを忘れないでください。これは、アプリのデータベース接続に大混乱をもたらす可能性もあります。私はこれをやっていると思っていましたが、確かに、カーソルを明示的に閉じていない場所を見つけました。だから、あなたのアプリを調べて、それらすべてを再確認してください。

シングルトンのDatabaseHelperオブジェクトも使用しています。SQLiteOpenHelperクラス内で静的DatabaseHelperオブジェクトを宣言して、毎回同じインスタンスを取得できるようにします。

これで、これらのDBエラーが発生しなくなった安定した実行中のアプリができました。この情報がお役に立てば幸いです。

于 2011-10-27T17:38:28.380 に答える
2

CursorAdapter.changeCursor(null)を使用してください。このバグの発生を遅らせることができますが、問題を完全に解決することはできません。不明な期間が再び表示されます。これも私を夢中にさせています!

于 2011-08-17T10:24:16.633 に答える
1

また、同じ問題が発生しました'dbは、fillWindow()およびIllegalStatementExceptionのカーソル無効ステートメントで例外をすでに閉じています'。私が行ったことは、カーソル(w / cもSimpleCursorAdapterから取得)をメソッド変数ではなくインスタンス変数に配置し、onStopメソッドとonPauseメソッドでstopManagingCursorを呼び出し、次にonResumeメソッドとonStartメソッドでstartManagingCursorを呼び出しました。

それは私にとって私の問題を解決しました、そして私はその後私のlogcatにエラーや警告メッセージを見つけませんでした:)これが誰かにも役立つことを願っています。

于 2012-04-10T18:37:22.163 に答える