5

このエラー メッセージに関する多くのトピックを読みましたが、問題を解決できません。

私は Google Play にアプリを持っており、ユーザーからいくつかのエラー レポートを受け取ります。アプリを試しているときは、すべて正常に動作します。

アプリケーションでは、30 個のテーブルを含む大きなデータベースを管理しています。メイン アクティビティ onDestroy() でデータベースを閉じています。クエリが終了すると、すべてのカーソルが閉じられます。

ユーザーが時々このエラーメッセージを受け取る理由は本当にわかりません。

エラーログ全体は次のとおりです。

java.lang.IllegalStateException: database /data/data/mdpi.android/databases/LocalDatabase.db (conn# 0) already closed
at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2213)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1565)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1525)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1605)
at mdpi.android.database.LocalDatabase.getHistoryLastSuccessfullUpdate(LocalDatabase.java:661)
at mdpi.android.Journals$7.onItemClick(Journals.java:723)
at android.widget.AdapterView.performItemClick(AdapterView.java:292)
at android.widget.Gallery.onSingleTapUp(Gallery.java:960)
at android.view.GestureDetector.onTouchEvent(GestureDetector.java:1310)
at android.widget.Gallery.onTouchEvent(Gallery.java:937)
at android.view.View.dispatchTouchEvent(View.java:5724)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1964)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1725)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1970)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1970)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1970)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1970)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1970)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1970)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1739)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2071)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
at android.app.Activity.dispatchTouchEvent(Activity.java:2426)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2019)
at android.view.View.dispatchPointerEvent(View.java:5904)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3155)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2670)
at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:1000)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2679)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)

そしてもう一つ:

java.lang.RuntimeException: Unable to start activity ComponentInfo{mdpi.android/mdpi.android.UserInformations}: java.lang.IllegalStateException: database /data/data/mdpi.android/databases/LocalDatabase.db (conn# 0) already closed
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2202)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2237)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4974)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: database /data/data/mdpi.android/databases/LocalDatabase.db (conn# 0) already closed
at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2194)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1536)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1496)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1576)
at mdpi.android.database.LocalDatabase.getUserInformations(LocalDatabase.java:357)
at mdpi.android.UserInformations.onCreate(UserInformations.java:122)
at android.app.Activity.performCreate(Activity.java:4538)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2158)
... 11 more

編集: 1 つの新しいエラー。

今日、データベース アクセスに関連する新しいエラーが発生しました。

java.lang.RuntimeException: An error occured while executing doInBackground()

at android.os.AsyncTask$3.done(AsyncTask.java:278)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException
at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:115)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1718)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1591)
at mdpi.android.database.LocalDatabase.insertCountry(LocalDatabase.java:143)
at mdpi.android.database.CountryTable.EnterCountry(CountryTable.java:21)
at mdpi.android.UserInformations$insertCountryAsync.doInBackground(UserInformations.java:270)
at mdpi.android.UserInformations$insertCountryAsync.doInBackground(UserInformations.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 4 more
4

4 に答える 4

2

onDestroy()アクティビティが終了/破棄/スタックから削除されたときにのみ呼び出されます。アクティビティから移動するときonStop()に呼び出されます。現在のデザインを保持する必要がある場合は、 close を呼び出すだけonStop()です。注:現在のアクティビティの onStop は、新しい/次のアクティビティの onCreate/onRestart の後に呼び出されます。

単一の DB がある場合は、pawelieba で言及されているように SQLiteOpenHelper クラスを使用できます。また、Application クラスで sqlite db 参照を使用でき、すべてのアクティビティで参照を使用できます

((MyApplication)getApplication()).db

onCreate()Application クラスの DB を開き、で閉じonTerminate()ます。

このエラーに対する他の SO の回答もご覧ください。以前から何度も質問されています。

java.lang.illegalstateexceptionデータベースが開いていませんandroid

Android java.lang.IllegalStateException データベースはすでに閉じられています

Android がデータを挿入する SQLite エラー java.lang.IllegalStateException が原因: データベースが開いていません

于 2012-11-12T04:33:21.703 に答える
1

私が取り組んだプロジェクトでも同様の問題がありました。

このプロジェクトでは、読み取り専用データベースからデータを取得するために使用される静的メソッドを備えた抽象クラスであるデータ アクセス レイヤー (DAL) を使用しました。メソッドは、データベースを開き、データを取得して、データベースを閉じました。これにより、データベースが閉じられたときに例外がスローされました。常にではなく、すべての電話ではありません。

コンテンツ プロバイダーを実装し、DAL の代わりにそれを使用すると、問題は解決しました。

于 2012-11-09T09:34:13.663 に答える
1

SQLite データベースには、アクセス可能なネイティブ インターフェースがあります。SQLiteDatabaseこのクラスは、異なるスレッドからネイティブ SQLite へのアクセスを同期化します。のインスタンスを提供するように処理する に
SQLiteDatabaseキャッシュされます。これはシングルトン パターンです。SQLiteOpenHelperSQLiteDatabase

私の経験からすると、 のインスタンスを 1 つ持って、そこからSQLiteOpenHelperキャッシュする必要がありSQLiteDatabaseます。そうすれば、開閉を気にする必要はありませんSQLiteDatabase

アプリで のインスタンスを 1 つ持つには、アプリケーションの の 1 つのインスタンスSQLiteOpenHelperが必要SQLiteDatabaseです。ネイティブ データベースへのマルチスレッド アクセスの問題を解決します。

要するにSQLiteOpenHelper、クエリごとにデータベースを取得するシングルトンです。
醜いシングルトン パターンに対処するために Roboguice を使用しています。

于 2012-11-05T10:14:01.707 に答える
0

必ず

  • クエリの後で cusor を閉じて、sqlite からデータを取得します。

  • 更新でトランザクションを使用し、sqlite に挿入します。

しかし、クエリ シーケンスで多くの JOIN を使用する場合があり、クエリするテンプル テーブルが作成され、すぐに閉じられなかった可能性があります。

于 2013-07-08T02:22:27.120 に答える