Android Question Map not initialized

Anser

Well-Known Member
Licensed User
Longtime User
Hi,

In my app I am using KVS to store the SMTP Server Detail etc. Inside the Activity_Create, I read the SMTP Server details from the KVS to a Map and then Initialize the SMTP object. Unfortunately, most of the time I get the Map Object not initialized error, it doesn't happen always. Once this starts to give error, then this is repeated, then I kill the app from the recent apps. Then it works.

Can anyone point me why this is happening only sometimes and not always. OR is there any other better way to achieve this

Here is the code that I use
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region
#Extends: android.support.v7.app.AppCompatActivity

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Private SMTP As SMTP
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")

    Activity.Color=Colors.RGB(228,228,228)
    ActionBar.Initialize("ActionBar")
    Activity.AddView(ActionBar,0,0,100%x,56dip)

    'Set the ToolBar (it is called ActionBar in the layout file) as the ActionBar of this activity.
    ActionBar.SetAsActionBar    
    ActionBar.Title = "Login"

' Set the Toolbar Shadow
    AC.SetElevation(ActionBar, 8dip)

    ABHelper.Initialize
    ABHelper.ShowUpIndicator = True
    ActionBar.InitMenuListener

    IME1.Initialize("IME1")

    Dim MapSmtpDtls As Map
    MapSmtpDtls.Initialize
    MapSmtpDtls = Starter.kvs.GetEncrypted("SmtpDetails", "MyPassword")
    If MapSmtpDtls.IsInitialized Then
        SMTP.Initialize( MapSmtpDtls.Get("SmtpServer"), MapSmtpDtls.Get("SmtpPort"), MapSmtpDtls.Get("SmtpUserID"), MapSmtpDtls.Get("SmtpPassword"), "SMTP")
    Else 'Most of the time the ELSE statement is executed ie Map is not initialized
        ToastMessageShow("Email Map not initialized",False)
        Activity.Finish
    End If

End Sub
Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

I assume that it must be something wrong in the way that I am coding.
Any help will be appreciated.

Regards

Anser
 

Anser

Well-Known Member
Licensed User
Longtime User
How and where do you save the map in the KVS?
It is done from the Activity_Create of my Main ie my Starting Activity. The problem that I reported happens in my second activity called from one of the menu options on the Main activity.

For Eg. Main
B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Get SMTP Server Details and store it to kvs
    GetSmtpDtls
End Sub

Sub GetSmtpDtls
    Dim cmd As DBCommand
    cmd.Initialize
    cmd.Name="get_smtp_dtls"
    'ProgressDialogShow("Retrieving data")
    Try
        reqManager.ExecuteQuery(cmd, 0, "GetSmtpDtls")
    Catch
        Msgbox("Could not establish connection with the server","Check Internet")
    End Try               
End Sub

Sub ReqManager_Result(result As DBResult)
    reqManager.PrintTable(result)

    If result.Tag = "GetSmtpDtls" Then 'SMTP Details
        Dim MapSmtpDtls As Map
        Dim Record() As Object
        Record = result.Rows.Get(0) ' The First Record, actualy there is only one record       
        MapSmtpDtls.Initialize
        MapSmtpDtls.Put("SmtpServer"  , Record(result.Columns.Get("smtp_Server"))         )
        MapSmtpDtls.Put("SmtpPort"    , Record(result.Columns.Get("smtp_Port"))           )
        MapSmtpDtls.Put("SmtpUserID"  , Record(result.Columns.Get("smtp_User_ID"))        )
        MapSmtpDtls.Put("SmtpPassword", Record(result.Columns.Get("smtp_User_Password"))  )               

        'Storing the SMTP details to kvs so that you don't need to read from RemoteDB all the time        
        If Starter.kvs.ContainsKey("SmtpDetails") Then
            Starter.kvs.Remove("SmtpDetails")
        Else
            Starter.kvs.PutEncrypted("SmtpDetails",MapSmtpDtls,"MyPassword")
        End If       

    End If
End Sub
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Given that you fill the map (and the KVS) in the Main Activity, it should work (although perhaps I'd move this code to the Starter service).

I could think that the map is not yet decrypted when you try to use it, perhaps the decryption takes time, even though they are little data.
MapSmtpDtls = Starter.kvs.GetEncrypted("SmtpDetails", "MyPassword")
' here the map could not be "ready"

If MapSmtpDtls.IsInitialized Then
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
I could think that the map is not yet decrypted when you try to use it, perhaps the decryption takes time, even though they are little data.

As you said that the decryption may take a bit time, So what is the best way to put a small/reasonable delay after
B4X:
MapSmtpDtls = Starter.kvs.GetEncrypted("SmtpDetails", "MyPassword")

So that the code
B4X:
If MapSmtpDtls.IsInitialized Then
is called/executed only after it is initialized

Or is there any other better method may be a For next loop until it is initialized
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
You mean in the Main ? Right ? and not in the second activity that is giving me the problem.

GetSmtpDels is called only once ie when I start my App.

Edit:- Tried moving the GetSmtpDtls from Activity_Create to Activity_Resume in the Main, unfortunately the result is same.
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
One more thing that I noticed is that this happens mostly when the app is run for the first time after compiling and installation on to the device/emulator from the IDE.

If I quit the app and restart the app, then the issue is not there.
 
Last edited:
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
Decryption doesn't take time to complete.

GetSmtpDels should be implemented in the starter service. This method does take time to complete as the value will only be available after ReqManager_Result is raised.
I think that I was not able to explain the issue properly.

In my Main, in the activity_create itself, I call GetSmtpDtls. GetSmtpDtls picks the SMTP details from a remote MySQL DB and as you said ReqManager_Result is raised and from ReqManager_Result, the retrieved data is written to the KVS, encrypted. There are other remote DB queries that are being called after this. I have put a Log() to ensure that the SMTP details are picked up from the DB and written to KVS store. As per the Log, the data is written to KVS before the main calls another activity. So till here it is OK.

After this, Main will call another activity named "HomePage". On the "HomePage" activity I have few menus. When I choose one of the menu's another activity named "SendEmail" is opened which requires to send an email. So here in the activity create, I try to read the encrypted data already available on the KVS to a Map. It is here that I am facing the problem.

May be here I could use another logic for eg, in the "SendEmail" activity_create I'll read the Encrypted KVS data to a map and I will initialize SMTP (using the Map) only in the button_click which actually start sending the email. So that there is enough time delay and the device gets enough time to read the encrypted data from the KVS and then the Map must have got initialized by that time.

ie instead of
B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")

    Activity.Color=Colors.RGB(228,228,228)
    ActionBar.Initialize("ActionBar")
    Activity.AddView(ActionBar,0,0,100%x,56dip)

    Dim MapSmtpDtls As Map
    MapSmtpDtls.Initialize
    MapSmtpDtls = Starter.kvs.GetEncrypted("SmtpDetails", "MyPassword")
    If MapSmtpDtls.IsInitialized Then
        SMTP.Initialize( MapSmtpDtls.Get("SmtpServer"), MapSmtpDtls.Get("SmtpPort"), MapSmtpDtls.Get("SmtpUserID"), MapSmtpDtls.Get("SmtpPassword"), "SMTP")
    Else 'Most of the time the ELSE statement is executed ie Map is not initialized
        ToastMessageShow("Email Map not initialized",False)
        Activity.Finish
    End If

End Sub
Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

I will modify as given below
B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")

    Activity.Color=Colors.RGB(228,228,228)
    ActionBar.Initialize("ActionBar")
    Activity.AddView(ActionBar,0,0,100%x,56dip)

    Dim MapSmtpDtls As Map 'This line will be moved to Sub Globals

    MapSmtpDtls.Initialize
    MapSmtpDtls = Starter.kvs.GetEncrypted("SmtpDetails", "MyPassword")

End Sub

Sub SendEmail_Click
    If MapSmtpDtls.IsInitialized Then
        SMTP.Initialize( MapSmtpDtls.Get("SmtpServer"), MapSmtpDtls.Get("SmtpPort"), MapSmtpDtls.Get("SmtpUserID"), MapSmtpDtls.Get("SmtpPassword"), "SMTP")
    Else 'Most of the time the ELSE statement is executed ie Map is not initialized
        ToastMessageShow("Email Map not initialized",False)
        Activity.Finish
    End If
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Regards
Anser
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I think that I was not able to explain the issue properly.

In my Main, in the activity_create itself, I call GetSmtpDtls. GetSmtpDtls picks the SMTP details from a remote MySQL DB and as you said ReqManager_Result is raised and from ReqManager_Result, the retrieved data is written to the KVS, encrypted. There are other remote DB queries that are being called after this. I have put a Log() to ensure that the SMTP details are picked up from the DB and written to KVS store. As per the Log, the data is written to KVS before the main calls another activity. So till here it is OK.

After this, Main will call another activity named "HomePage". On the "HomePage" activity I have few menus. When I choose one of the menu's another activity named "SendEmail" is opened which requires to send an email. So here in the activity create, I try to read the encrypted data already available on the KVS to a Map. It is here that I am facing the problem.
Given that you fill the map (and the KVS) in the Main Activity, it should work (although perhaps I'd move this code to the Starter service).


For some reason it is not so, otherwise it would work.
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
Actually I am puzzled, why this is failing only at some point of time. If it fails, then if I start my app once again, it works fine.

Anyway, as suggested by both you and Erel, let me try moving the GetSmtpDtls to Starter Service.

Do you think that it is better to use the Starter Service for all my database related handling OR a separate service just to handle database . As of now, I am using jRDC2 separately in each and every Activity and NOT using a service for this.
 
Upvote 0
Top