Android Tutorial StateManager - Helps managing Android applications settings and state

Status
Not open for further replies.
Edit: StateManager was written in 2011. I don't recommend using it for new projects. Use B4XPages + KVS2 instead.

StateManager is a code module which takes care of handling the application UI state and settings.

Settings
Settings are the application configurable settings. These settings should be permanently kept.

The methods for handling settings are pretty simple:
StateManager.GetSetting (Key As String) As String: gets the value associated with the given key. An empty string will return if the key is not available. The settings will be loaded from a file if they were not loaded before.

StateManager.GetSetting2 (Key As String, DefaultValue As String) As String: similar to GetSetting. The DefaultValue will return if the key was not found.

StateManager.SetSetting(Key As String, Value As String): Associates the given value with the gives key. Note that there is no need to call SaveSettings after each call to SetSetting.

StateManager.SaveSettings: saves the settings to a file. Usually you will want to call this method in Activity_Pause.

UI State
The UI state is a bit more interesting. In some cases Android may destroy our activity and then recreate it when needed. This happens for example when the user changes the screen orientation. If the user has entered some text in an EditText view then we want to keep this text. So instead of resetting the UI we are first saving the state and then we will restore it.

Not all the elements are saved. Only elements which the user interacts with (like EditText text, Spinner chosen item, SeekBar value...).
Using StateManager to handle the state is simple:
B4X:
Sub Activity_Create(FirstTime As Boolean)

    ...
    'Load the previous state
    If StateManager.RestoreState(Activity, "Main", 60) = False Then
        'set the default values
        EditText1.Text = "Default text"
        EditText2.Text = "Default text"
    End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then
        StateManager.ResetState("Main")
    Else
        StateManager.SaveState(Activity, "Main")
    End If
    StateManager.SaveSettings
End Sub
When the activity is paused we check if the user chose to close the activity (by pressing on the Back key). In that case we reset the state. The string parameter is the ActivityName value. StateManager can manage the state of multiple activities so the name is used to differentiate between the activities.
If UserClosed=False then we want to save the state.
The settings are saved in both cases.

When the activity is created we call: StateManager.RestoreState. The last parameter is the validity period for this state. The state will not be loaded if more than the specified minutes have passed. Pass 0 for an unlimited period.
RestoreState returns a boolean value. It returns true if the state was loaded. If the state wasn't loaded it is your responsibility to set the default value. This will be the case when the user runs the application for the first time.

To use StateManager you should choose Project - Add Existing Module and add StateManager.bas which is included in the attached example. You should also add a reference to the RandomAccessFile library and Reflection library.

statemanager_1.png


Version 1.11 is attached. It adds support for saving and restoring TabHost views with their internal views.
 

Attachments

  • StateManager.zip
    11.7 KB · Views: 1,677
Last edited:

Claudio Oliveira

Active Member
Licensed User
Longtime User
Hey everybody,
I noticed that every time I used StateManager to save/restore CheckBox states, it did save/restore the CheckBox label instead, and not it's checked state as it was supposed to. And the same happened to ToggleButton and RadioButton. o_O
I'm running Android 5.0.1 on a Samsung Galaxy S4.
After some logging, I found out that CheckBoxes trigger the "Label" section of the "if ... else" structure in StateManager code.
I was not quite sure about the reason for such unexpected behaviour, but I guessed it was because a CheckBox, Toggle and Radio Buttons are sort of "composite" views. They have the label and functional part (check box or toggle) together.
Maybe Erel could clarify this point...
Anyway, I positioned the CheckBox's, RadioButton's and ToggleButton's code sections BEFORE the Label's code section in the "if ... else" structure in both innerSaveState and innerRestoreState subs.
Everything's working fine now.

Regards,
Claudio Oliveira
Rio de Janeiro - Brasil
 

Yves Mazzon

Member
Licensed User
Longtime User
StateManager is a code module which takes care of handling the application UI state and settings.

Erel, I have been trying your example StateManager.zip but it doesn't work for me. I try to understand how it works but when the example is not working it makes worst.I'm getting the following error message:

B4A version 4.30 BETA 1
Parsing code. 0.02
Compiling code. 0.05
Compiling layouts code. Error
Value cannot be null.
Parameter name: input
Error File: 1.bal
Go to the designer script page to debug this error.

The designer is not showing anything.

Yves
 

Yves Mazzon

Member
Licensed User
Longtime User
Dear Erel, I need a push start on StateManager. How can I apply it to my code. Where the bas module has to be placed? Do I have to modify the stageManager.bas for my application? Many thanks for your time. Hopefully soon I will stop asking stupid questions.
Yves
 

Claudio Oliveira

Active Member
Licensed User
Longtime User
@Yves Mazzon save the layout file after you open it and it will work.

StateManager doesn't do anything with labels. Maybe you have downloaded the wrong module.
Yeah. That's right.
I've donwloaded the correct module now. StateManager indeed has nothing to do with labels at all.
Now I've got to find out WHERE did I get this module from!!! :D
Thanks Erel
 

Yves Mazzon

Member
Licensed User
Longtime User
Thanks Erel but I must be missing something. I have added the module with the "Add Existing Module" and pointed to the satemanager.bas in the same folder where the .b4a is. Didn't modified my code but when I compile I get an error see attach. Did I get the right satemanager.bas see also attached? Really getting stuck with this.
Thank you
 

Attachments

  • Error.JPG
    Error.JPG
    65.9 KB · Views: 378
  • StateManager.bas
    6.9 KB · Views: 371

Yves Mazzon

Member
Licensed User
Longtime User
See the error message. You need to add a reference to the RandomAccessFile library.
Thank you Erel but I'm a beginner and need to get a bit more explanation. Sorry for my ignorance. How do I add a reference to the RandomAccessFile library?
Many thanks for your help.
Regards,
Yves
 

Nb1320

Member
Licensed User
Longtime User
Hello,
Is it possible to pull the information from the save file that the statemanager creates and make a list(s) out of it for another activity in the app?

Thanks!
 

Adilson Jacinto

Active Member
Licensed User
Longtime User
StateManager is a code module which takes care of handling the application UI state and settings.

Settings
Settings are the application configurable settings. These settings should be permanently kept.

The methods for handling settings are pretty simple:
StateManager.GetSetting (Key As String) As String: gets the value associated with the given key. An empty string will return if the key is not available. The settings will be loaded from a file if they were not loaded before.

StateManager.GetSetting2 (Key As String, DefaultValue As String) As String: similar to GetSetting. The DefaultValue will return if the key was not found.

StateManager.SetSetting(Key As String, Value As String): Associates the given value with the gives key. Note that there is no need to call SaveSettings after each call to SetSetting.

StateManager.SaveSettings: saves the settings to a file. Usually you will want to call this method in Activity_Pause.

UI State
The UI state is a bit more interesting. In some cases Android may destroy our activity and then recreate it when needed. This happens for example when the user changes the screen orientation. If the user has entered some text in an EditText view then we want to keep this text. So instead of resetting the UI we are first saving the state and then we will restore it.

Not all the elements are saved. Only elements which the user interacts with (like EditText text, Spinner chosen item, SeekBar value...).
Using StateManager to handle the state is simple:
B4X:
Sub Activity_Create(FirstTime As Boolean)

    ...
    'Load the previous state
    If StateManager.RestoreState(Activity, "Main", 60) = False Then
        'set the default values
        EditText1.Text = "Default text"
        EditText2.Text = "Default text"
    End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then
        StateManager.ResetState("Main")
    Else
        StateManager.SaveState(Activity, "Main")
    End If
    StateManager.SaveSettings
End Sub
When the activity is paused we check if the user chose to close the activity (by pressing on the Back key). In that case we reset the state. The string parameter is the ActivityName value. StateManager can manage the state of multiple activities so the name is used to differentiate between the activities.
If UserClosed=False then we want to save the state.
The settings are saved in both cases.

When the activity is created we call: StateManager.RestoreState. The last parameter is the validity period for this state. The state will not be loaded if more than the specified minutes have passed. Pass 0 for an unlimited period.
RestoreState returns a boolean value. It returns true if the state was loaded. If the state wasn't loaded it is your responsibility to set the default value. This will be the case when the user runs the application for the first time.

To use StateManager you should choose Project - Add Existing Module and add StateManager.bas which is included in the attached example. You should also add a reference to the RandomAccessFile library and Reflection library.

statemanager_1.png


Version 1.11 is attached. It adds support for saving and restoring TabHost views with their internal views.


Hi Erel,

How do I add the StateManager? is that a library? it is because I cannot find it.
 

agb2008

Member
Licensed User
Longtime User
In my application I've tried to replace my custom state_save/state_restore functions with StateManager ones...
But I was unable to succeed - probably because of my application design - could you please advice if it's indeed the
case or if I am doing something wrong.

In my case I've use following code in Activity_Create module:

B4X:
    Activity.LoadLayout("Main")
   
    scvMain.Height=-1
    scvMain.Width=-1

    scvMain.Panel.LoadLayout("Panel1")
    scvMain.Panel.LoadLayout("Panel2")
    scvMain.Panel.LoadLayout("Panel3")
    scvMain.Panel.LoadLayout("Panel4")
    scvMain.Panel.LoadLayout("Panel5")
   
    scvMain.Panel.Height = pnlCalc1.Height

Where Main layout consist of just single ScrollView object. And Panel1 - Panel5 are panels created in Visual Designer.
(Main layout [scvMain] created in Visual Designer as well) Initially only Panel1 is in Visible state, other panels hidden.
When needed application control which panel became active and user could input/change some info on these panels.

Problem as I've observed it is that when I am using StateManager to save application state for example to avoid data
loss during screen rotation procedure only information from first Panel1 saved...

So my question is: could StateManager save information from multiple panels, some of which are in not Visible state or
it would only deal with main active object ?
 
Status
Not open for further replies.
Top