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,873
Last edited:

roarnold

Active Member
Licensed User
Longtime User
Erel,

I like it, works well. Question. Each time the app is run it will process the State Manager app, correct?

Thanks,
R
 

luthepa1

Member
Licensed User
Longtime User
Ok I got something weird.... I have added the StateManager code module to project and all is working. If i enter text into a edittext view and rotate screen (so activity destroyed and recreated) the edittext view is repopulated witht eh text I had entered before rotating device. So that is good. All is working. But when I check a checkbox view and rotate screen/device the check status of that checkbox view is not restored! Not sure why?

I did make a edit to the innerSaveState and innerRestoreState to include the enabled status of button views. And when rotating my device the enabled status of the button is appropriately restored. So that works too!

I added a toast message tot he checkbox CheckChanged event and it shows true for checked and false for unchecked. The only other code that interacts with these checkbox view at the moment is positioning them on the screen with the Left statement. Nothing else.

Anybody have ideas why my checkbox view states are not restored? Code below

B4X:
Sub innerSaveState(v As View, list1 As List)
   Dim data() As Object
   If v Is Button Then      'DrP - Added button enabled status - 11JUL12
      Dim btn As Button
      btn = v
      data = Array As Object(btn.Enabled)
   Else If v Is EditText Then



Sub innerRestoreState(v As View, list1 As List)
   Dim data() As Object
   If v Is Button Then
      Dim btn As Button
      btn = v
      data = getNextItem(list1)
      btn.Enabled = data(0)
   Else If v Is EditText Then

B4X:
Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("CreateWorkoutMain.bal")
   scvCreateWorkout.Panel.LoadLayout("CreateWorkout.bal")
   
   InitCreateWorkoutLayout
   
   StateManager.RestoreState(Activity, "CreateWorkout", 60)
End Sub

Sub Activity_Pause (UserClosed As Boolean)
If UserClosed Then
        StateManager.ResetState("CreateWorkout")
    Else
        StateManager.saveState(Activity, "CreateWorkout")
    End If
End Sub
 

luthepa1

Member
Licensed User
Longtime User
Yes. CheckBox is a special type of button. In your code you should first check for CheckBox and only then for Button.

Thanks Erel! That worked! Although I must admit I dont understand why it makes a difference? I mean each view has its state saved to a object list. I guess its something to do with what you ay about the checkbox view being a "special type of button".

Dont suppose you can fill me in or point me to a link that describes why? My curious mind wont give up. :D
 

BarrySumpter

Active Member
Licensed User
Longtime User
Just finished a layout for user properties and settings.
Like UserID and Password and RefreshRate, etc.

Then was wondering how to save the data.

Using StateManager I can't believe I need only two statements!

(unless I'm missing somthing)


B4X:
Sub Activity_Create(FirstTime As Boolean)
....
    'Load the previous state
    If StateManager.RestoreState(Activity, "Main", 60) = False Then
        'set the default values
    End If

End Sub

Sub Activity_Pause (UserClosed As Boolean)

        StateManager.SaveState(Activity, "Main")

End Sub

Freakin' Brilliant!
:sign0098:

Can't believe how quicky my design, testing, and apps are progressing.
 
Last edited:

barx

Well-Known Member
Licensed User
Longtime User
Looking through this code module, it doesn't seem to save any state for WebView, is this correct. If so, is there anyway to save WebView state?

I know I could save the current URL on Activity_Pause and ReLoad it on Activity_Resume but is there any way to save any text that has been entered into a text field on a site? i.e. the user decides to rotate device part way through replying to a forum post on a site. I doubt there will be a way but just thought I'd ask.

Thanks.
 

fajar

New Member
Licensed User
Longtime User
Reflector

can't run StateManagerExample sample
why reflector marked-on red?
 

enrico

Active Member
Licensed User
Longtime User
Prevent orientation change

I'm struggling in using State Manager properly for my project and I'm asking if there is a way to block the screen orientation change only in some activities.
I don't care if it's vertical or horizontal, but I would not want that it could be changed (only in this activity).
 

enrico

Active Member
Licensed User
Longtime User
I was thinking Phone.SetScreenOrientation can't do the job.
Can you please post a code example ?
 

enrico

Active Member
Licensed User
Longtime User
Ok, it works. I did not realize that it also blocks from rotating. Thanks
 
Status
Not open for further replies.
Top