Android Question Initializing the database

Sergey_New

Well-Known Member
Licensed User
Longtime User
The application creates a user database.
The application initializes the database on command.
Then the application completely closes.
The next time you open the application, the database remains initialized.
Why does this happen and how can you avoid it?
Example attached.
I need your help.
 

Attachments

  • test.zip
    3.5 KB · Views: 129

emexes

Expert
Licensed User
Longtime User
the database remains initialized

What is the warning or error message in the Log that indicates the database remains initialized?

Given that the database is a Map in memory and not a file, it is indeed surprising that it would retain its state across program runs.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
What is the warning or error message in the Log that indicates the database remains initialized?
No error occurs. Everything is visible in the example.
 
Upvote 0

walt61

Well-Known Member
Licensed User
Longtime User
Then the application completely closes.

I have the impression that that's not happening in Sub CloseActivity - at least, the application isn't completely terminated (the process isn't killed). If that code is changed like this, the behaviour does change and the database is not initialised the next time the app is started:

B4X:
Sub CloseActivity
    ExitApplication
End Sub
 
Upvote 0

emexes

Expert
Licensed User
Longtime User
the behaviour does change and the database is not initialised the next time the app is started:

Agreed because, when an app starts, all memory variables, including the Map "database", are cleared back to null/zero/empty ie not yet initialized.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
I would like to advise you to consider Erel's advice to develop new projects in cross-platform B4XPages and use as many B4X components as possible to have the least impact from Android quirks.

My advice is to use B4XMainPage only for program initialization and shared variables. Although the command B4XPages.ShowPageAndRemovePreviousPages does not produce an error message, it looks like that the B4XMainPage remains in memory and is only invisible for the user, maybe because of the mentioned shared variables. I avoid using the B4XMainPage for programming routines after running into a hard-to-spot problem when refreshing page views.

If you use B4XPages you can call a subroutine when closing the B4XPage. Here you can either close the (sub)B4XPage, or quit the program. Regardless of whether this works or not, it eliminates the need to use your Java object routine.

Another possibility is to ask the user whether all data should be thrown away or stored in a database. (file). Because a B4XPages is a separate class file, you can reuse it in other projects by importing this class file into the new project. This makes reusability and software maintenance easier.

Also note that B4XPages makes it easier for you to detect if your user completes an input activity without the change being written to the database.

I also wonder if you are not overlooking the difference between testing whether a class and a database are both initialized. You call an initialization routine and with that the class or module is initialized and therefore True. This is separate from initializing a database. To avoid this misunderstanding, you can better make a global variable in the initialization routine of the database routine and makes it True when a routine is called successfully (without errors is processed), which is set to False by default.

You have the ability to handle the following specific situations in B4XPages with the routines below

B4XPages sub routines:
'    ---This event will be called once, before the page becomes visible.
'    --- Called once when the page Is created. This will happen before the page
'    --- becomes visible Or after a call To B4XPages.AddPageAndCreate.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
End Sub

'--- Called whenever the page becomes visible.
Private Sub B4XPage_Appear
    
End Sub

'--- Called whenever a visible page disappears.
Private Sub B4XPage_Disappear
    
End Sub

'    --- Called when the app Is moved To the background. This event will be
'    --- raised in all pages that implement this sub, not just the top event. This is a good place to save
'    --- anything that needs To be save As the process might be killed later. Note that in B4J it Is raised when
'    --- the last page Is closed.
Private Sub B4XPage_Background
    
End Sub

'    --- Called when the app moved To the foreground.
Private Sub B4XPage_Foreground
    
End Sub

'    ---  (B4J / B4i) - Called when the page Is resized.
#IF B4J
    Private Sub B4XPage_Resize
'        --- Only used in B4J
    End Sub
#End If
    
#IF B4I
    Private Sub B4XPage_Resize
'        --- Only used in B4I
    End Sub
#End If
    
'    --- (B4J / B4A) - In B4A it Is called when the user clicks on the back key Or
'    --- on the up indicator. In B4J it is called when the user clicks on the close button
#IF B4J
    Private Sub B4XPage_CloseRequest
'        --- Only used in B4J
    End Sub
#End If

#IF B4A
    Private Sub B4XPage_CloseRequest
    
    End Sub
#End If

'    --- on the up indicator. 'In B4J it Is called when the user clicks on the close button.
'    --- Called when a menu item Or BarButton in B4i Is clicked.
#IF B4J
    Private Sub B4XPage_MenuClick
'        --- Only used in B4J
    End Sub
#End If

#IF b4I
    Private Sub B4XPage_MenuClick
'        --- Only used in B4I
    End Sub
#End If

'    --- (B4i) - Called when the keyboard state changes.
#IF B4I
    Private Sub B4XPage_KeyboardStateChanged
'        --- Only used in B4I       
    End Sub
#End If

'    --- (B4J) - Called when a page Is minimized Or restored.
Private Sub B4XPage_IconifiedChanged
    
End Sub

'    --- (B4A) - Raised after a call To rp.CheckAndRequest.
'    --- rp = RuntimePermissions, the B4A RuntimePermissions library.
#IF B4A
    Private Sub B4XPage_PermissionResult
'        --- Only used in B4A
    End Sub
#End If

#IF B4J
    Private Sub B4XPage_Resize
'        --- Only used in B4J
    End Sub
#End If
    
#IF B4I
    Private Sub B4XPage_Resize
'        --- Only used in B4I
    End Sub
#End If
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
I would like to advise you to consider Erel's advice to develop new projects in cross-platform B4XPages
Thank you!
But today I have a task to implement everything planned in B4A. Perhaps the next stage is the transition to B4XPages.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
Oh well, it took Microsoft years to migrate the persistent Windows XP and VB6 users, so there's still hope there

As for your in-memory SQLite database, you'll have to think very carefully about how to open only ONE in-memory database and close the SAME in-memory database because if you have multiple in-memory databases, you're likely to get mixed up. And if you have multiple concurrent "users", in wal mode can throw a spanner in the works.
.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
It turned out that when closing the application by command:
B4X:
Sub CloseActivity
    Dim jo As JavaObject
    jo.InitializeContext
    jo.RunMethod("finishAndRemoveTask", Null)
End Sub
when reopening the application, the starter service does not run.
What can be done to start the starter service?
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
What can be done to start the starter service?
Well, I don't want to be a pain in the ass, but from what I understand, your goal is to clean up the in-memory database when you close the application. Therefore, leave the starter service alone and focus on the SQLite way, but be aware that a shared SQLite database can be blocked by another user.

Open and remove in-memory SQLite database:
'    --- Open SQLite database
    sql1.Initialize("", ":memory:", True)
    
'    --- Close and remove SQLite database
        sql1.Close
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
leave the starter service alone and focus on the SQLite way
The example given uses a simple database. My database is much more complex and I am not going to convert it to a SQLite database yet.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
The example given uses a simple database. My database is much more complex and I am not going to convert it to a SQLite database yet.
No need, the point is that when closing the in-memory database it is removed from memory. If the in-memory is very complex, it may take a while before everything in memory is cleared. Perhaps you can first be rough by including a very large delay to see if that helps or if it is really gone, or perhaps you can look at the wall file to see if it has already been cleared. I think that when closing the database, even with the in-memory version, the database is first written away and only then removed. If you kill the process during that process, perhaps not everything is cleared.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
I don't understand the point of your proposal. Change my example without converting its database to SQLite and show the result.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
Dear Sergey, you talk about a database and give an example of a memory variable. These are two completely different things. Cleaning up a variable is done with the garbage routine that in principle only starts when there is a lack of memory space. Whether it follows the logic of, mark the empty variable as "deleted" (note, nothing has been thrown away yet) and if you then immediately create an empty variable with the same name or the operating system is then smart to convert the marking "not used" back to "in use" (efficient memory usage), I cannot rule out. Look closely, you either create an in-memory database or use a copy of a class in a memory object that you empty with a null command or something like that.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
What can be done to start the starter service?
After kicking in a locked door, you should at least repair the door. If you insist on using the routine from post 11, the simple answer is:
Update post 11 'kicking in a locked door' routine:
Sub CloseActivity
    Dim jo As JavaObject
    jo.InitializeContext
    jo.RunMethod("finishAndRemoveTask", Null)
    StartActivity(Me)
End Sub
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
StartActivity(Me)
Before giving advice, read the question carefully.
It is required that the starter service is enabled the next time the application is launched.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
Before giving advice, read the question carefully.
It is required that the starter service is enabled the next time the application is launched.
Dear Sergey, I have read your confusing question well. The short answer is to reboot to avoid any side effects of your chose.

You are mixing up the terms database and variables to hide what you really want to achieve programmatically. Then you continue to stick to the violent means with all kinds of side effects that you have chosen, without the goal being clear.

It is just like the example of the kicked-in door. In itself, a logical wish to be able to lock the kicked-in door again. But which usually cannot be fulfilled. But that is simply the result of the conscious choice to kick in the door and not use a key when passing the locked door.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…