Bug? Zero length Map file if stopping debugger

yo3ggx

Active Member
Licensed User
Longtime User
Hi,

If I'm stopping an application using a map file in debugger mode (by pressing STOP button), at next start the map file is empty (0 length).
This does not happen at each start, but it can be easily replicated by stopping and starting the application several times.
I've built a small example app (attached) to demonstrate this behavior.

There is no view on the Activity. The application just load and then save some variables from/to a map. At each start the length of the loaded map file is logged. If you start in debugger mode (legacy) and then press stop (square button in IDE) for a few times you will get a zero length map.

Thank you,
Dan
 

Attachments

  • MapBug.zip
    301.2 KB · Views: 141

derez

Expert
Licensed User
Longtime User
When stopping the debugger the application does not go through Activity_pause. If you stopped it while in the file write process - you loose the file and then your code starts an empty map.
If you change the code like this you'll always have the map , at least with the defaults.
B4X:
If FirstTime Then
       If File.Exists(File.DirInternal,"myconfig.cfg") Then
            cfgGeneral = File.ReadMap(File.DirInternal,"myconfig.cfg")
            Log("map size =" & cfgGeneral.Size)
        Else
            cfgGeneral.Initialize
            cfgGeneral.Put("string",S)
            cfgGeneral.Put("integer",I)
            cfgGeneral.Put("long",L)
            cfgGeneral.Put("bool",B)
        End If
        S = cfgGeneral.GetDefault("string","")
        I = cfgGeneral.GetDefault("integer",0)
        L = cfgGeneral.GetDefault("long",0)
        B = cfgGeneral.GetDefault("bool",False)
        File.WriteMap(File.DirInternal,"myconfig.cfg",cfgGeneral)
    End If
 

yo3ggx

Active Member
Licensed User
Longtime User
Hi David,

Thank you for your answer.
My experience was that I get the zero length map even stopping the debugger when the application is idle.
Your code example is not good in my situation for two reasons:
- whenever I get a zero length map file, the file is there, so the line
B4X:
If File.Exists(File.DirInternal,"myconfig.cfg")
will always return true after first start, even if the file is zero length;
- as I'm using the map file to store application configuration data, reverting to defaults each time I get a zero length map is not acceptable.

There is any other workaround for this? I have the impression (still need to confirm this) that the map file content is lost even when running in Release mode, if the application crashes (with Java error). For sure the crash is not in File.WriteMap function, so no reason to corrupt the file, Is this an expected behavior?

Best regards,
Dan
 

derez

Expert
Licensed User
Longtime User
I think i know the reason for the problem !
Try to store the file in another place (like dirrootexternal).
The directory dirinternal is cleared each time you install.
I can't check because my computer broke down...
 

yo3ggx

Active Member
Licensed User
Longtime User
I think i know the reason for the problem !
Try to store the file in another place (like dirrootexternal).
The directory dirinternal is cleared each time you install.
I can't check because my computer broke down...
This is a vey good observation, but then is strange that sometimes the file is there after a new installation and the data available.
I think that when a new version is installed, the files in dirrootinternal are not fully deleted, but I cannot find why is triggering this behavior.

Thank you,
Dan
 

yo3ggx

Active Member
Licensed User
Longtime User
Done some tests. The file is no more zero length if using DirRootExternal. I'm using the following code:

B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

End Sub

Sub Activity_Create(FirstTime As Boolean)
     If FirstTime Then
        If File.Exists(File.DirRootExternal,"myconfig.cfg") Then
            cfgGeneral = File.ReadMap(File.DirRootExternal,"myconfig.cfg")
            Log("map size =" & cfgGeneral.Size)
        Else
            cfgGeneral.Initialize
        End If
        cfgGeneral.Put("string",S)
        cfgGeneral.Put("integer",I)
        cfgGeneral.Put("long",L)
        cfgGeneral.Put("bool",B)
        File.WriteMap(File.DirRootExternal,"myconfig.cfg",cfgGeneral)
    End If
End Sub

Sub Activity_Resume
    S = cfgGeneral.GetDefault("string","")
    I = cfgGeneral.GetDefault("integer",0)
    L = cfgGeneral.GetDefault("long",0)
    B = cfgGeneral.GetDefault("bool",False)
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    cfgGeneral.Put("string",S)
    cfgGeneral.Put("integer",I)
    cfgGeneral.Put("long",L)
    cfgGeneral.Put("bool",B)
    File.WriteMap(File.DirRootExternal,"myconfig.cfg",cfgGeneral)
End Sub

Just one observation:
When I'm stopping the app by pressing STOP button in the debugger, in the log file I get
** Activity (main) Pause, UserClosed = true **
so the Activity goes through Pause when stopping.

Thank you,
Dan
 

derez

Expert
Licensed User
Longtime User
Glad it is solved.
if you use this for configuration only may be a better solution is KVS (key value store).
Using kvs you set the parameters directly to the stored file and you have to store only the changed parameters,
 

yo3ggx

Active Member
Licensed User
Longtime User
Glad it is solved.
if you use this for configuration only may be a better solution is KVS (key value store).
Using kvs you set the parameters directly to the stored file and you have to store only the changed parameters,

I was not aware about this class. I will take a look.
Thank you again,

Dan
 

derez

Expert
Licensed User
Longtime User
If you have a questiongo to "questions" and there on top right you have "start new thread"
 
Top