我已经阅读了很多关于此错误消息的主题,但我无法解决我的问题。
我在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
答案 0 :(得分:2)
onDestroy()
。当您离开活动时,将调用onStop()
。如果您需要保留当前的设计,只需在onStop()
中调用close即可。 注意:当前活动的onStop将在新/下一个活动的onCreate / onRestart之后调用。
如果你有一个单独的数据库,你可以使用pawelieba提到的SQLiteOpenHelper类 您还可以在Application类中使用sqlite db引用,并且只需在所有活动中使用该引用,例如
((MyApplication)getApplication()).db
只需在Application类的onCreate()
中打开数据库,然后在onTerminate()
中将其关闭。
您还可以查看此错误的其他SO答案。之前有很多次问过。
java.lang.illegalstateexception database not open android
Android java.lang.IllegalStateException database already closed
Android insert the data SQLite error Caused by java.lang.IllegalStateException: database not open
答案 1 :(得分:1)
SQLite数据库具有可通过SQLiteDatabase
访问的本机接口 - 此类负责同步对来自不同线程的本机SQLite的访问。
SQLiteDatabase
缓存在SQLiteOpenHelper
中,负责提供SQLiteDatabase
的实例,它是单例模式。
根据我的经验,您应该有一个SQLiteOpenHelper
实例并从中获取缓存SQLiteDatabase
。然后你不需要注意关闭/打开SQLiteDatabase
。
应用程序的SQLiteOpenHelper
的一个实例对于在应用程序中拥有SQLiteDatabase
的单个实例是必要的。它将解决对本机数据库的多线程访问问题。
简而言之:SQLiteOpenHelper
的单例,您可以从中获取每个查询的数据库
我正在使用Roboguice来处理丑陋的单身模式。
答案 2 :(得分:1)
我在一个项目中遇到过类似的问题。
该项目使用了数据访问层(DAL),这是一个抽象类,其静态方法用于从只读数据库中检索数据。这些方法打开了数据库,检索了数据并关闭了数据库。这导致在关闭数据库时抛出异常。并非总是而且并非所有手机都没有。
当我实现content provider并使用它而不是DAL时,问题就消失了。
答案 3 :(得分:0)
确保
查询后关闭cusor以从sqlite获取数据。
在更新中使用事务,插入到sqlite。
但是有些时候我们可能在查询序列中使用了很多JOIN,它创建了要查询的temple表,也许它没有立即关闭