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

编辑:一个新错误。

今天,我得到一个与数据库访问有关的新错误:

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 in onStop()注意:当前活动的 onStop 将在新/下一个活动的 onCreate/onRestart 之后调用。

如果您有一个单独的数据库,则可以使用 pawelieba 提到的 SQLiteOpenHelper 类您也可以在 Application 类中使用 sqlite db 引用,并且可以在所有活动中使用该引用,例如

((MyApplication)getApplication()).db

onCreate()只需打开Application 类的 DB并在onTerminate().

您还可以查看此错误的其他 SO 答案。之前已经问过很多次了。

java.lang.illegalstateexception 数据库未打开android

Android java.lang.IllegalStateException 数据库已经关闭

Android 插入数据 SQLite 错误 Caused by java.lang.IllegalStateException: database not open

于 2012-11-12T04:33:21.703 回答
1

SQLite 数据库具有可通过本机接口访问的本机接口SQLiteDatabase- 此类负责同步从不同线程对本机 SQLite 的访问。
SQLiteDatabase被缓存在SQLiteOpenHelper其中负责提供的实例SQLiteDatabase,它是单例模式。

根据我的经验,您应该拥有一个实例SQLiteOpenHelper并从中获取缓存SQLiteDatabase。那么你不需要照顾关闭/打开SQLiteDatabase

应用程序的一个实例SQLiteOpenHelper必须在应用程序中有一个实例SQLiteDatabase。它将解决多线程访问本机数据库的问题。

简而言之:SQLiteOpenHelper您可以从中获取每个查询的数据库的单例。
我正在使用 Roboguice 来处理丑陋的单例模式。

于 2012-11-05T10:14:01.707 回答
1

在我从事的一个项目中,我遇到了类似的问题。

该项目使用了数据访问层 (DAL),它是一个抽象类,具有用于从只读数据库中检索数据的静态方法。这些方法打开数据库,检索数据并关闭数据库。这导致在关闭数据库时引发异常。并非总是如此,也并非在所有手机上。

当我实现内容提供程序并使用它而不是 DAL 时,问题就消失了。

于 2012-11-09T09:34:13.663 回答
0

确定

  • 查询后关闭光标以从 sqlite 获取数据。

  • 在更新中使用事务,插入到 sqlite。

但是有时我们可能在查询序列中使用了很多 JOIN,它创建了 Temple 表来查询并且可能没有立即关闭

于 2013-07-08T02:22:27.120 回答