Should we stay away from closing a SQLite database with SQL1.Close when dealing with B4XPages. But, if we have to close it, where is the best place to place the command without crashing the code..
I've been playing about with B4XPages and a couple of SQLite database lately. I've just used .Close after I finish using the SQL Object in the same function block of code, I've not come across any crashes...
I've been playing about with B4XPages and a couple of SQLite database lately. I've just used .Close after I finish using the SQL Object in the same function block of code, I've not come across any crashes...
Here is a case in point where I had a crash:
1.I run the app, then I click a button in B4XMainPage to display on a label the SQLite version on device.
2. I exit the app via the back key code which closes the database: SQL1.Close.
3. I click on the app icon , it displays the B4XPage. Now I click on the button to display the SQL version on a label, but app crashes with the below error.
B4X:
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /storage/emulated/0/test/test.db
Oh I get what you are saying now, sorry.
I believe that I reinitialize the DB in on B4XPage_Appear - Called whenever the page becomes visible, but without looking at the code (I'm currently on my phone) I can't really remember. I know that I always close the SQLite databases on exiting the app though, well not unless it's processing data which is one of the reasons I like B4XPages, it allows for continuous processing of data in the background.
I'll be back home shortly, I'll fire uup my laptop to double check that I am using B4XPage_Appear.
I close the database in the back key code. So, how do you avoid the crash?
Here is the code:
B4X:
Private Sub B4XPage_CloseRequest As ResumableSub
Dim sf As Object = xui.Msgbox2Async("Do you want to Exit ?", "Exit", "Yes", "Cancel", "No", Null)
Wait For (sf) Msgbox_Result (Result As Int)
If Result = xui.DialogResponse_Positive Then
SQL1.Close
Return True
End If
Return False
End Sub
Hello,
I've just got back in from a quick come ride and checked my code.
I don't use B4XPages_Appear, that section of code is commented out, I use B4XPages_Foreground, but I don't close the database in B4XPage_Background, I close the database whenever it finishes it task, basically in the same sub.
In a few previous projects I have left the database open, but it completely depends on the project...
But does .Close is close the cursor, not the database. Why not just Open the Cursor do the SQL then Close the Cursor? Keep it fairly atomic and clean. This is what I do for my DB operations - especially if deleting items. Plus I find it better in terms of stability and different Android versions and SQL versions.
I have a database stored in DirExternal with rtp that is shared by a few applications, what happened if another app without B4Xpages opens the database that is already open by the app that makes use of B4XPages. I have a feeling a crash will be unavoidable. I have not tested B4XPage_Background and B4XPage_Foreground because I did not get that far yet, but it seems B4XPage open in the foregroud and close in the background might be the only way to go in my situations to insure a crash avoidance.
I just added the 2 subs to the app. It is working well so far, as I got no crash in subsequent runs. I have not tested another app that accesses this database yet to check the behavior when another app opens the same database. Hopefully, everything will be kosher.
B4X:
Sub B4XPage_Background
lbl.Text=""
SQL1.Close
End Sub
B4X:
Sub B4XPage_Foreground
If SQL1.IsInitialized =False Then
SQL1.Initialize(DBFilePath,DBFileName,True)
End If
End Sub