I'm writing an app which has 2 activities and gets his data from a
database. Unfortunately I'm not sure when I have to open and close the
database properly. In both activities I'm opening the database so the
activities can access its data. When I do the following:
* Start the app
* Open activity 1
* Open activity 2 (via button in activity 1)
* Hit the back button (back to activity 1)
* Again back button (back to home screen)
* Start the app
I'm receiving such an leak error:
07-15 14:34:19.504: ERROR/Database(234): Leak found
07-15 14:34:19.504: ERROR/Database(234):
java.lang.IllegalStateException: mPrograms size 1
07-15 14:34:19.504: ERROR/Database(234): at
android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:
1669)
07-15 14:34:19.504: ERROR/Database(234): at
dalvik.system.NativeStart.run(Native Method)
07-15 14:34:19.504: ERROR/Database(234): Caused by:
java.lang.IllegalStateException: /data/data/de.anote/databases/
anote.db SQLiteDatabase created and never closed
.... more stuff .....
I guess it is because I'm not closing the database so implemented the
following:
* db.open() in both onCreate() and both onResume() methods by the 2
activities
* db.close() in both onPause() methods.
But now I'm receiving another error:
07-15 15:27:18.472: ERROR/AndroidRuntime(266): Uncaught handler:
thread main exiting due to uncaught exception
07-15 15:27:18.508: ERROR/AndroidRuntime(266):
java.lang.RuntimeException: Unable to resume activity {de.anote/
de.anote.gui.CategoryView}: java.lang.IllegalStateException: mQuery
SELECT _id, note_name, value, date, category, priority, reminderbool,
reminder, todo FROM t_note WHERE category=? ORDER BY date 1
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.app.ActivityThread.performResumeActivity(ActivityThread.java:
2950)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.app.ActivityThread.handleResumeActivity(ActivityThread.java:
2965)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1889)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.os.Handler.dispatchMessage(Handler.java:99)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.os.Looper.loop(Looper.java:123)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.app.ActivityThread.main(ActivityThread.java:4363)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
java.lang.reflect.Method.invokeNative(Native Method)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
java.lang.reflect.Method.invoke(Method.java:521)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
com.android.internal.os.ZygoteInit
$MethodAndArgsCaller.run(ZygoteInit.java:860)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
dalvik.system.NativeStart.main(Native Method)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by:
java.lang.IllegalStateException: mQuery SELECT _id, note_name, value,
date, category, priority, reminderbool, reminder, todo FROM t_note
WHERE category=? ORDER BY date 1
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:162)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:536)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.app.Activity.performRestart(Activity.java:3736)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.app.Activity.performResume(Activity.java:3756)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.app.ActivityThread.performResumeActivity(ActivityThread.java:
2937)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 10 more
07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by:
android.database.sqlite.SQLiteMisuseException: library routine called
out of sequence: handle 0x0
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.database.sqlite.SQLiteProgram.native_bind_string(Native
Method)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:
178)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): at
android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:153)
07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 14 more
Unfortunately I can't read which line in my code causes this exception
but I guess it is because there is some point where is a database
access and the db is still closed.
So my question is, at which places should I open and close my
database? It is right to open it in the onCreate(), onResume() methods
and close it in onPause()?
Probably by opening the db both in onCreate() and onResume() in some circustances (e.g. first execution of your app) the db will be opened twice, which for sure is not good. If you open the db only in onResume() it should be fine (although I didn't try it by myself). Usually, when I need data from the db, I call db.open(), fetch my data, and db.close(). In this way I'm pretty sure there won't be any such leak. Still I don't know if that's "the best way" to do it.
On Thu, Jul 15, 2010 at 3:51 PM, Bender <abende...@googlemail.com> wrote: > Hi,
> I'm writing an app which has 2 activities and gets his data from a > database. Unfortunately I'm not sure when I have to open and close the > database properly. In both activities I'm opening the database so the > activities can access its data. When I do the following:
> * Start the app > * Open activity 1 > * Open activity 2 (via button in activity 1) > * Hit the back button (back to activity 1) > * Again back button (back to home screen) > * Start the app
> I'm receiving such an leak error:
> 07-15 14:34:19.504: ERROR/Database(234): Leak found > 07-15 14:34:19.504: ERROR/Database(234): > java.lang.IllegalStateException: mPrograms size 1 > 07-15 14:34:19.504: ERROR/Database(234): at > android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java: > 1669) > 07-15 14:34:19.504: ERROR/Database(234): at > dalvik.system.NativeStart.run(Native Method) > 07-15 14:34:19.504: ERROR/Database(234): Caused by: > java.lang.IllegalStateException: /data/data/de.anote/databases/ > anote.db SQLiteDatabase created and never closed
> .... more stuff .....
> I guess it is because I'm not closing the database so implemented the > following:
> * db.open() in both onCreate() and both onResume() methods by the 2 > activities > * db.close() in both onPause() methods.
> But now I'm receiving another error:
> 07-15 15:27:18.472: ERROR/AndroidRuntime(266): Uncaught handler: > thread main exiting due to uncaught exception > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): > java.lang.RuntimeException: Unable to resume activity {de.anote/ > de.anote.gui.CategoryView}: java.lang.IllegalStateException: mQuery > SELECT _id, note_name, value, date, category, priority, reminderbool, > reminder, todo FROM t_note WHERE category=? ORDER BY date 1 > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.app.ActivityThread.performResumeActivity(ActivityThread.java: > 2950) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.app.ActivityThread.handleResumeActivity(ActivityThread.java: > 2965) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.app.ActivityThread$H.handleMessage(ActivityThread.java:1889) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.os.Handler.dispatchMessage(Handler.java:99) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.os.Looper.loop(Looper.java:123) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.app.ActivityThread.main(ActivityThread.java:4363) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > java.lang.reflect.Method.invokeNative(Native Method) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > java.lang.reflect.Method.invoke(Method.java:521) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > com.android.internal.os.ZygoteInit > $MethodAndArgsCaller.run(ZygoteInit.java:860) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > dalvik.system.NativeStart.main(Native Method) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by: > java.lang.IllegalStateException: mQuery SELECT _id, note_name, value, > date, category, priority, reminderbool, reminder, todo FROM t_note > WHERE category=? ORDER BY date 1 > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:162) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:536) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.app.Activity.performRestart(Activity.java:3736) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.app.Activity.performResume(Activity.java:3756) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.app.ActivityThread.performResumeActivity(ActivityThread.java: > 2937) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 10 more > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by: > android.database.sqlite.SQLiteMisuseException: library routine called > out of sequence: handle 0x0 > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.database.sqlite.SQLiteProgram.native_bind_string(Native > Method) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java: > 178) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:153) > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 14 more
> Unfortunately I can't read which line in my code causes this exception > but I guess it is because there is some point where is a database > access and the db is still closed.
> So my question is, at which places should I open and close my > database? It is right to open it in the onCreate(), onResume() methods > and close it in onPause()?
> -- > You received this message because you are subscribed to the Google > Groups "Android Beginners" group.
> To unsubscribe from this group, send email to > android-beginners+unsubscribe@googlegroups.com<android-beginners%2Bunsubscr ibe@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/android-beginners?hl=en
Thanks for your reply. I tried to open the db only in onResume() but
that doesn't work since there are db accesses in the onCreate() method
which is called before onResume() as far as I know. I think opening
and closing the db after every access would slow the app down a lot
because i'm using the db in almost every method. I hope there is
another solution for it..
On 15 Jul., 16:07, YuviDroid <yuvidr...@gmail.com> wrote:
> Probably by opening the db both in onCreate() and onResume() in some
> circustances (e.g. first execution of your app) the db will be opened twice,
> which for sure is not good.
> If you open the db only in onResume() it should be fine (although I didn't
> try it by myself). Usually, when I need data from the db, I call db.open(),
> fetch my data, and db.close(). In this way I'm pretty sure there won't be
> any such leak. Still I don't know if that's "the best way" to do it.
> YuviDroid
> On Thu, Jul 15, 2010 at 3:51 PM, Bender <abende...@googlemail.com> wrote:
> > Hi,
> > I'm writing an app which has 2 activities and gets his data from a
> > database. Unfortunately I'm not sure when I have to open and close the
> > database properly. In both activities I'm opening the database so the
> > activities can access its data. When I do the following:
> > ═* Start the app
> > ═* Open activity 1
> > ═* Open activity 2 (via button in activity 1)
> > ═* Hit the back button (back to activity 1)
> > ═* Again back button (back to home screen)
> > ═* Start the app
> > I guess it is because I'm not closing the database so implemented the
> > following:
> > ═* db.open() in both onCreate() and both onResume() methods by the 2
> > activities
> > ═* db.close() in both onPause() methods.
> > But now I'm receiving another error:
> > 07-15 15:27:18.472: ERROR/AndroidRuntime(266): Uncaught handler:
> > thread main exiting due to uncaught exception
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266):
> > java.lang.RuntimeException: Unable to resume activity {de.anote/
> > de.anote.gui.CategoryView}: java.lang.IllegalStateException: mQuery
> > SELECT _id, note_name, value, date, category, priority, reminderbool,
> > reminder, todo FROM t_note WHERE category=? ORDER BY date 1
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.app.ActivityThread.performResumeActivity(ActivityThread.java:
> > 2950)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.app.ActivityThread.handleResumeActivity(ActivityThread.java:
> > 2965)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.app.ActivityThread$H.handleMessage(ActivityThread.java:1889)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.os.Handler.dispatchMessage(Handler.java:99)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.os.Looper.loop(Looper.java:123)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.app.ActivityThread.main(ActivityThread.java:4363)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > java.lang.reflect.Method.invokeNative(Native Method)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > java.lang.reflect.Method.invoke(Method.java:521)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > com.android.internal.os.ZygoteInit
> > $MethodAndArgsCaller.run(ZygoteInit.java:860)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > dalvik.system.NativeStart.main(Native Method)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by:
> > java.lang.IllegalStateException: mQuery SELECT _id, note_name, value,
> > date, category, priority, reminderbool, reminder, todo FROM t_note
> > WHERE category=? ORDER BY date 1
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:162)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:536)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.app.Activity.performRestart(Activity.java:3736)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.app.Activity.performResume(Activity.java:3756)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.app.ActivityThread.performResumeActivity(ActivityThread.java:
> > 2937)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ ... 10 more
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by:
> > android.database.sqlite.SQLiteMisuseException: library routine called
> > out of sequence: handle 0x0
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.database.sqlite.SQLiteProgram.native_bind_string(Native
> > Method)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:
> > 178)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ at
> > android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:153)
> > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ═ ═ ... 14 more
> > Unfortunately I can't read which line in my code causes this exception
> > but I guess it is because there is some point where is a database
> > access and the db is still closed.
> > So my question is, at which places should I open and close my
> > database? It is right to open it in the onCreate(), onResume() methods
> > and close it in onPause()?
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Android Beginners" group.
> > To unsubscribe from this group, send email to
> > android-beginners+unsubscribe@googlegroups.com<android-beginners%2Bunsubscr ibe@googlegroups.com>
> > For more options, visit this group at
> >http://groups.google.com/group/android-beginners?hl=en
On Thu, Jul 15, 2010 at 4:49 PM, Bender <abende...@googlemail.com> wrote: > Thanks for your reply. I tried to open the db only in onResume() but > that doesn't work since there are db accesses in the onCreate() method > which is called before onResume() as far as I know. I think opening > and closing the db after every access would slow the app down a lot > because i'm using the db in almost every method. I hope there is > another solution for it..
> On 15 Jul., 16:07, YuviDroid <yuvidr...@gmail.com> wrote: > > Probably by opening the db both in onCreate() and onResume() in some > > circustances (e.g. first execution of your app) the db will be opened > twice, > > which for sure is not good. > > If you open the db only in onResume() it should be fine (although I > didn't > > try it by myself). Usually, when I need data from the db, I call > db.open(), > > fetch my data, and db.close(). In this way I'm pretty sure there won't be > > any such leak. Still I don't know if that's "the best way" to do it.
> > YuviDroid
> > On Thu, Jul 15, 2010 at 3:51 PM, Bender <abende...@googlemail.com> > wrote: > > > Hi,
> > > I'm writing an app which has 2 activities and gets his data from a > > > database. Unfortunately I'm not sure when I have to open and close the > > > database properly. In both activities I'm opening the database so the > > > activities can access its data. When I do the following:
> > > * Start the app > > > * Open activity 1 > > > * Open activity 2 (via button in activity 1) > > > * Hit the back button (back to activity 1) > > > * Again back button (back to home screen) > > > * Start the app
> > > I guess it is because I'm not closing the database so implemented the > > > following:
> > > * db.open() in both onCreate() and both onResume() methods by the 2 > > > activities > > > * db.close() in both onPause() methods.
> > > But now I'm receiving another error:
> > > 07-15 15:27:18.472: ERROR/AndroidRuntime(266): Uncaught handler: > > > thread main exiting due to uncaught exception > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): > > > java.lang.RuntimeException: Unable to resume activity {de.anote/ > > > de.anote.gui.CategoryView}: java.lang.IllegalStateException: mQuery > > > SELECT _id, note_name, value, date, category, priority, reminderbool, > > > reminder, todo FROM t_note WHERE category=? ORDER BY date 1 > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.app.ActivityThread.performResumeActivity(ActivityThread.java: > > > 2950) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.app.ActivityThread.handleResumeActivity(ActivityThread.java: > > > 2965) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.app.ActivityThread$H.handleMessage(ActivityThread.java:1889) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.os.Handler.dispatchMessage(Handler.java:99) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.os.Looper.loop(Looper.java:123) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.app.ActivityThread.main(ActivityThread.java:4363) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > java.lang.reflect.Method.invokeNative(Native Method) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > java.lang.reflect.Method.invoke(Method.java:521) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > com.android.internal.os.ZygoteInit > > > $MethodAndArgsCaller.run(ZygoteInit.java:860) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > dalvik.system.NativeStart.main(Native Method) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by: > > > java.lang.IllegalStateException: mQuery SELECT _id, note_name, value, > > > date, category, priority, reminderbool, reminder, todo FROM t_note > > > WHERE category=? ORDER BY date 1 > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:162) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:536) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.app.Activity.performRestart(Activity.java:3736) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.app.Activity.performResume(Activity.java:3756) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.app.ActivityThread.performResumeActivity(ActivityThread.java: > > > 2937) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 10 more > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by: > > > android.database.sqlite.SQLiteMisuseException: library routine called > > > out of sequence: handle 0x0 > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.database.sqlite.SQLiteProgram.native_bind_string(Native > > > Method) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java: > > > 178) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at > > > android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:153) > > > 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 14 more
> > > Unfortunately I can't read which line in my code causes this exception > > > but I guess it is because there is some point where is a database > > > access and the db is still closed.
> > > So my question is, at which places should I open and close my > > > database? It is right to open it in the onCreate(), onResume() methods > > > and close it in onPause()?
> > > -- > > > You received this message because you are subscribed to the Google > > > Groups "Android Beginners" group.
> > > To unsubscribe from this group, send email to > > > android-beginners+unsubscribe@googlegroups.com<android-beginners%2Bunsubscr ibe@googlegroups.com> > <android-beginners%2Bunsubscribe@googlegroups.com<android-beginners%252Buns ubscribe@googlegroups.com>
> To unsubscribe from this group, send email to > android-beginners+unsubscribe@googlegroups.com<android-beginners%2Bunsubscr ibe@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/android-beginners?hl=en
> Thanks for your reply. I tried to open the db only in onResume() but > that doesn't work since there are db accesses in the onCreate() method > which is called before onResume() as far as I know. I think opening > and closing the db after every access would slow the app down a lot > because i'm using the db in almost every method. I hope there is > another solution for it..
> On 15 Jul., 16:07, YuviDroid<yuvidr...@gmail.com> wrote:
>> Probably by opening the db both in onCreate() and onResume() in some >> circustances (e.g. first execution of your app) the db will be opened twice, >> which for sure is not good. >> If you open the db only in onResume() it should be fine (although I didn't >> try it by myself). Usually, when I need data from the db, I call db.open(), >> fetch my data, and db.close(). In this way I'm pretty sure there won't be >> any such leak. Still I don't know if that's "the best way" to do it.
>> YuviDroid
>> On Thu, Jul 15, 2010 at 3:51 PM, Bender<abende...@googlemail.com> wrote:
>>> Hi,
>>> I'm writing an app which has 2 activities and gets his data from a >>> database. Unfortunately I'm not sure when I have to open and close the >>> database properly. In both activities I'm opening the database so the >>> activities can access its data. When I do the following:
>>> * Start the app >>> * Open activity 1 >>> * Open activity 2 (via button in activity 1) >>> * Hit the back button (back to activity 1) >>> * Again back button (back to home screen) >>> * Start the app
>>> I'm receiving such an leak error:
>>> 07-15 14:34:19.504: ERROR/Database(234): Leak found >>> 07-15 14:34:19.504: ERROR/Database(234): >>> java.lang.IllegalStateException: mPrograms size 1 >>> 07-15 14:34:19.504: ERROR/Database(234): at >>> android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java: >>> 1669) >>> 07-15 14:34:19.504: ERROR/Database(234): at >>> dalvik.system.NativeStart.run(Native Method) >>> 07-15 14:34:19.504: ERROR/Database(234): Caused by: >>> java.lang.IllegalStateException: /data/data/de.anote/databases/ >>> anote.db SQLiteDatabase created and never closed
>>> .... more stuff .....
>>> I guess it is because I'm not closing the database so implemented the >>> following:
>>> * db.open() in both onCreate() and both onResume() methods by the 2 >>> activities >>> * db.close() in both onPause() methods.
>>> But now I'm receiving another error:
>>> 07-15 15:27:18.472: ERROR/AndroidRuntime(266): Uncaught handler: >>> thread main exiting due to uncaught exception >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): >>> java.lang.RuntimeException: Unable to resume activity {de.anote/ >>> de.anote.gui.CategoryView}: java.lang.IllegalStateException: mQuery >>> SELECT _id, note_name, value, date, category, priority, reminderbool, >>> reminder, todo FROM t_note WHERE category=? ORDER BY date 1 >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.app.ActivityThread.performResumeActivity(ActivityThread.java: >>> 2950) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.app.ActivityThread.handleResumeActivity(ActivityThread.java: >>> 2965) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.app.ActivityThread$H.handleMessage(ActivityThread.java:1889) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.os.Handler.dispatchMessage(Handler.java:99) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.os.Looper.loop(Looper.java:123) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.app.ActivityThread.main(ActivityThread.java:4363) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> java.lang.reflect.Method.invokeNative(Native Method) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> java.lang.reflect.Method.invoke(Method.java:521) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> com.android.internal.os.ZygoteInit >>> $MethodAndArgsCaller.run(ZygoteInit.java:860) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> dalvik.system.NativeStart.main(Native Method) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by: >>> java.lang.IllegalStateException: mQuery SELECT _id, note_name, value, >>> date, category, priority, reminderbool, reminder, todo FROM t_note >>> WHERE category=? ORDER BY date 1 >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:162) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:536) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.app.Activity.performRestart(Activity.java:3736) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.app.Activity.performResume(Activity.java:3756) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.app.ActivityThread.performResumeActivity(ActivityThread.java: >>> 2937) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 10 more >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): Caused by: >>> android.database.sqlite.SQLiteMisuseException: library routine called >>> out of sequence: handle 0x0 >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.database.sqlite.SQLiteProgram.native_bind_string(Native >>> Method) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java: >>> 178) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): at >>> android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:153) >>> 07-15 15:27:18.508: ERROR/AndroidRuntime(266): ... 14 more
>>> Unfortunately I can't read which line in my code causes this exception >>> but I guess it is because there is some point where is a database >>> access and the db is still closed.
>>> So my question is, at which places should I open and close my >>> database? It is right to open it in the onCreate(), onResume() methods >>> and close it in onPause()?
>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Android Beginners" group.
>>> To unsubscribe from this group, send email to >>> android-beginners+unsubscribe@googlegroups.com<android-beginners%2Bunsubscr ibe@googlegroups.com> >>> For more options, visit this group at >>> http://groups.google.com/group/android-beginners?hl=en
The problem I'm having with this is, that there is always a new
DbAdapter created which is fine when the activity is created the first
time. But this way "mDb.getDatabase() == null" will be always true
because its a new mDb.
So I either need to find a way to check if the database is opened
without "mDb" or need to remember mDb even if the activity is stopped.
@Kostya Vasilyev
I tried that, but then my app crashes while switching between
activities. When I was searching for the error I put logs in the
open() and close() methods by my DbAdapter and I could see the
following:
* open() (app, activity1 started)
* open() (i hit a button in activity1, activity2 is starting and
open is called within onStart)
* close() (activity1 is stopped, in onStop close is called)
When I go back to activity1 it throws an exception because the
database is closed. -.-
mmm I'm not really sure what you are trying to achieve. Exactly, at what times do you want to open/close the db? The db should stay open while your application is running? So, even when you switch among activities (yours activities)?
> The problem I'm having with this is, that there is always a new > DbAdapter created which is fine when the activity is created the first > time. But this way "mDb.getDatabase() == null" will be always true > because its a new mDb.
> So I either need to find a way to check if the database is opened > without "mDb" or need to remember mDb even if the activity is stopped.
> @Kostya Vasilyev
> I tried that, but then my app crashes while switching between > activities. When I was searching for the error I put logs in the > open() and close() methods by my DbAdapter and I could see the > following:
> * open() (app, activity1 started) > * open() (i hit a button in activity1, activity2 is starting and > open is called within onStart) > * close() (activity1 is stopped, in onStop close is called)
> When I go back to activity1 it throws an exception because the > database is closed. -.-
> -- > You received this message because you are subscribed to the Google > Groups "Android Beginners" group.
> To unsubscribe from this group, send email to > android-beginners+unsubscribe@googlegroups.com<android-beginners%2Bunsubscr ibe@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/android-beginners?hl=en
I want to get rid of the error which is telling me that there is a
leak in my app because my db gets opened twice. The db doesn't need to
be open the whole time but it is accessed quite often so I don't think
it would be very performant to open and close it for every access.
On 16 Jul., 09:10, YuviDroid <yuvidr...@gmail.com> wrote:
> mmm I'm not really sure what you are trying to achieve. Exactly, at what
> times do you want to open/close the db? The db should stay open while your
> application is running? So, even when you switch among activities (yours
> activities)?
> On Thu, Jul 15, 2010 at 6:36 PM, Bender <abende...@googlemail.com> wrote:
> > @YuviDroid
> > I'm trying the following at the moment: the open() only gets called in
> > both onCreate() methods with:
> > The problem I'm having with this is, that there is always a new
> > DbAdapter created which is fine when the activity is created the first
> > time. But this way "mDb.getDatabase() == null" will be always true
> > because its a new mDb.
> > So I either need to find a way to check if the database is opened
> > without "mDb" or need to remember mDb even if the activity is stopped.
> > @Kostya Vasilyev
> > I tried that, but then my app crashes while switching between
> > activities. When I was searching for the error I put logs in the
> > open() and close() methods by my DbAdapter and I could see the
> > following:
> > ═* open() ═(app, activity1 started)
> > ═* open() ═(i hit a button in activity1, activity2 is starting and
> > open is called within onStart)
> > ═* close() ═(activity1 is stopped, in onStop close is called)
> > When I go back to activity1 it throws an exception because the
> > database is closed. -.-
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Android Beginners" group.
> > To unsubscribe from this group, send email to
> > android-beginners+unsubscribe@googlegroups.com<android-beginners%2Bunsubscr ibe@googlegroups.com>
> > For more options, visit this group at
> >http://groups.google.com/group/android-beginners?hl=en
put your db in a local Service. Open the db in onCreate() close it in
onDestroy(). Your Activities can bind and unbind to the Service as
many times as you like. The system will keep the service running as
long as you have an activity in the foreground process bound to it or
otherwise until it needs to reclaim the resources.
but DONT have your binder as a non-static inner class as in the
example - or you will create a memory leak and leak your Service.
Instead, pass the binder a reference to your service in onCreate and
get the binder to null the reference out in onDestroy
Thanks for your reply, and sorry for my late answer. :-)
I tried to get it running as a service but I don't really get how I
have to use services, binders and service connections. I'm reading a
book with an example for services but can't adopt it to my problem.
What I tried is the following:
I created one class for the service, which holds the variable for my
database:
__________________
public class DatabaseService extends Service {
public DbAdapter mDbAdapter;
private DatabaseBinder mDatabaseBinder = new DatabaseBinder();
@Override
public IBinder onBind(Intent intent) {
return mDatabaseBinder;
}
@Override
public void onCreate() {
super.onCreate();
mDatabaseBinder.mDatabaseService = this;
mDbAdapter = new DbAdapter(getApplicationContext());
mDbAdapter.open();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
}
If I want to use this in my activity with this:
private DatabaseBinder mDatabaseBinder;
private DbServiceConnection mServiceConnection = new
DbServiceConnection(mDatabaseBinder);
final Intent databaseServiceIntent = new Intent(this,
DatabaseService.class);
this.bindService(databaseServiceIntent, mServiceConnection,
Context.BIND_AUTO_CREATE);
mDb = mDatabaseBinder.getDbAdapter();
I'm getting a nullpointer exception at the last line. I don't know if
I'm using it right (I guess not :D ), I haven't used services before.
Do you know why it is throwing a Nullpointer exception? Is this the
right way to use a service and bind it in the activity or should I do
it somehow different?
On 19 Jul., 00:30, brucko <geoff.bruck...@gmail.com> wrote:
> put your db in a local Service. Open the db in onCreate() close it in
> onDestroy(). Your Activities can bind and unbind to the Service as
> many times as you like. The system will keep the service running as
> long as ═you have an activity in the foreground process bound to it or
> otherwise until it needs to reclaim the resources.
> but DONT have your binder as a non-static inner class as in the
> example - or you will create a memory leak and leak your Service.
> Instead, pass the binder a reference to your service in onCreate and
> get the binder to null the reference out in onDestroy
Starting / binding to a service is asynchronous. You can't call bindService and expect it to be already started and bound by the next line.
Call bindService and return control to Android by returning from onCreate or whatever. Your service connection callback will be invoked a little later, once the service is started.
Thanks for your reply, and sorry for my late answer. :-)
I tried to get it running as a service but I don't really get how I have to use services, binders and service connections. I'm reading a book with an example for services but can't adopt it to my problem. What I tried is the following:
I created one class for the service, which holds the variable for my database: __________________
public class DatabaseService extends Service {
public DbAdapter mDbAdapter; private DatabaseBinder mDatabaseBinder = new DatabaseBinder();
@Override public IBinder onBind(Intent intent) { return mDatabaseBinder; }
@Override public void onCreate() { super.onCreate(); mDatabaseBinder.mDatabaseService = this; mDbAdapter = new DbAdapter(getApplicationContext()); mDbAdapter.open(); }
@Override public void onServiceDisconnected(ComponentName arg0) { }
}
If I want to use this in my activity with this:
private DatabaseBinder mDatabaseBinder; private DbServiceConnection mServiceConnection = new DbServiceConnection(mDatabaseBinder);
final Intent databaseServiceIntent = new Intent(this, DatabaseService.class); this.bindService(databaseServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
mDb = mDatabaseBinder.getDbAdapter();
I'm getting a nullpointer exception at the last line. I don't know if I'm using it right (I guess not :D ), I haven't used services before. Do you know why it is throwing a Nullpointer exception? Is this the right way to use a service and bind it in the activity or should I do it somehow different?
On 19 Jul., 00:30, brucko <geoff.bruck...@gmail.com> wrote:
> but DONT have your binder as a non-static inner class as in the > example - or you will create a...
ATTENTION: Android-Beginners will be permanently disabled on August 9 2010. For more information about this change, please read [http://goo.gl/xkfl] or visit the Group home page.
Ok I tried to find out at which point the service is started and when
I can access its database variable. The logs I used showed that the
services onCreate() is called after the onResume() method by my
activity. That is a bit late because I need access to the database
before onResume() to fill the views with data. Is there a way to tell
the activity to wait until the service is started?
On 5 Aug., 22:54, Kostya Vasilyev <kmans...@gmail.com> wrote:
> Starting / binding to a service is asynchronous. You can't call bindService
> and expect it to be already started and bound by the next line.
> Call bindService and return control to Android by returning from onCreate or
> whatever. Your service connection callback will be invoked a little later,
> once the service is started.
Ok I tried to find out at which point the service is started and when I can access its database variable. The logs I used showed that the services onCreate() is called after the onResume() method by my activity. That is a bit late because I need access to the database before onResume() to fill the views with data. Is there a way to tell the activity to wait until the service is started?
On 5 Aug., 22:54, Kostya Vasilyev <kmans...@gmail.com> wrote:
> Starting / binding to a service is ... > 06.08.2010 0:49 пользователь "Bender" <abende...@googlemail.com> написал:
-- You received this message because you are subscribed to the Google Groups "Android Beginners"...
ATTENTION: Android-Beginners will be permanently disabled on August 9 2010. For more information abo...
mServiceConnection = new
DbServiceConnection(mDatabaseBinder);
final Intent databaseServiceIntent = new Intent(this,
DatabaseService.class);
this.bindService(databaseServiceIntent, mServiceConnection,
Context.BIND_AUTO_CREATE);
Did you mean that? Now it should wait until the mDatabaseBinder is set
which should be in the onServiceConnected() method but that code
results in an endless loop, mDatabaseBinder stays null. Maybe I got it
wrong how the components work together. As far as I understood it, you
have a service running in the background, which returns a binder in
onBind(). The service connection "fills" the binder
onServiceConnected() so it can be used in the activity to access the
services variables. Is that wrong?
On 6 Aug., 10:26, Kostya Vasilyev <kmans...@gmail.com> wrote:
Android framework is largely single-threaded, event-driven.
This means that your application and the framework run on the same thread, passing control to each other, doing work in small pieces. This thread is called the UI thread, and blocking it by calling sleep() can do only one thing - cause the "Application Not Responding" dialog to appear.
The right thing to do is call bindService, and return from onResume.
You've done your piece of work (responded to onResume, and requested that Android bind a service). Now you need to give Android a chance to do its piece of work - by returning from onResume into Android framework code, which will start the service (if necessary) and bind it, notifying your callback.
Then it's your turn again - once in the ServiceConnection callback, you know the service has been bound, and you can talk to the service and ultimately populate the UI.
So that's basically the scheme with services.
You might also want to look at ContentProviders. They have a few advantages over Services for this case - their lifecycle is managed by Android, access is synchronous (using ContentResolver), and they handle propagating data changes to existing queries / cursors (so if you have a ListView, its data will be "live").
> Did you mean that? Now it should wait until the mDatabaseBinder is set > which should be in the onServiceConnected() method but that code > results in an endless loop, mDatabaseBinder stays null. Maybe I got it > wrong how the components work together. As far as I understood it, you > have a service running in the background, which returns a binder in > onBind(). The service connection "fills" the binder > onServiceConnected() so it can be used in the activity to access the > services variables. Is that wrong?
> On 6 Aug., 10:26, Kostya Vasilyev<kmans...@gmail.com> wrote:
>> Sure. The service connection callback you seem to already have in your code.