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

jkurant

Member
Licensed User
Longtime User
But I have RandomAccessFile.jar and RandomAccessFile.xml in my C:\Program Files (x86)\Anywhere Software\Basic4android\Libraries folder. I don't understand why it is not working. Could someone look at my project files? I just attached the zip file.
 

Attachments

  • KurantMeds.zip
    16.4 KB · Views: 534

jkurant

Member
Licensed User
Longtime User
Also, I have confirmed that C:\Program Files (x86)\Anywhere Software\Basic4android\Libraries is the proper location because it is shown on the Configure Paths screen as the folder for Additional Libraries. RandomAccessFile is still showing in bright red.
 

jkurant

Member
Licensed User
Longtime User
Ahh, yes, thank you. I keep forgetting about those tabs in the lower right corner.

However, during the time I couldn't get the RandomAccessFile to work, I went back to using PreferencesActivity. I am not even using the UI part of it, but am just reading and writing the preferences using preferences.GetString and preferences.SetString.

Unless someone can tell me this is a bad idea, I think I will just keep using PreferencesActivity.
 

dbcrosby

Member
Licensed User
Longtime User
I have an app that I clear the display and then display the Progress Dialog while I'm loading files from the server.
My problem is, if the android device is rotated during the time the Progress Dialog is showing, I loose the progress dialog and the screen repaints with the old information even thou I cleared it. I need to keep the screen cleared and the progress dialog displayed until it's done loading the files. I am using the State Manger to handle device rotation.
Thanks!
 

Penko

Active Member
Licensed User
Longtime User
Erel, just wanted to thank you for this module.

I've included two methods in a code file and am posting the code in case someone finds it useful:

In my case the Code Module is called "Common".

CodeModule Sub actRestoreState - called in Activity_Create
B4X:
   Sub actRestoreState(Activity As Activity, activityname As String, validperiodinminutes As Int)

   If StateManager.RestoreState(Activity, activityname, validperiodinminutes) = False Then
   
      ' you can select case here based on activity and set default values
      
    End If

End Sub
   
' CodeModule Sub actSaveResetState - called in Activity_Paused
   Sub actSaveResetState(Activity As Activity, activityname, UserClosed As Boolean)
       
   If UserClosed Then
           StateManager.ResetState(activityname)
       Else
           StateManager.SaveState(Activity, activityname)
       End If
      
          StateManager.SaveSettings
   End Sub

It's only two function calls that we have to add in order to get it working. I am posting my original subs in order to see how these calls combine with other code. Also note that you should have loaded the layout file before trying to restore the values.

B4X:
Sub Activity_Pause (UserClosed As Boolean)
   If(AppSettings.debug_mode) Then
      Common.LogT("Activity_Pause()", "ACTIVITY_EVENT")
   End If
   
   Common.actSaveResetState(Activity, "AddEditFile", UserClosed)
End Sub

B4X:
Sub Activity_Create(FirstTime As Boolean)

   Activity.LoadLayout("layAddEditFile_def")
      
   If(AppSettings.debug_mode) Then
      Common.LogT("Activity_Create()  FirstTime = " & FirstTime, "ACTIVITY_EVENT")
   End If
   
   
   setEverything
   
   Common.actRestoreState(Activity, "AddEditFile", 0)
   
End Sub
 

RBeaubien

Member
Licensed User
Longtime User
Erel,

I am getting an error on line 14:

If Settings.IsInitialized = False Then

I/It can't find the definition of .IsInitialized

Where should that be declared? Am I missing something?

(Using B4A 1.90, RandomAccessfile 1.30, Reflection 1.90)

Thanx,

Rob
 

RBeaubien

Member
Licensed User
Longtime User
It is:

Dim Settings As Map

Just doesn't seem to have .IsInitialized as a property or method OR I have some incorrect lib referenced or missing. Where is Map declared?
 

Kevin

Well-Known Member
Licensed User
Longtime User
I didn't go back and read this thread or search the forum, but I think I recall seeing a post by Erel that we should check to see if the state was restored in Activity_Create.

Originally the example showed it being done in Activity_Restore and it was later said that it was wrong and was then revised.

My app is pretty complicated as far as restoring or not restoring the state. Because I got all of this coded and working before the correction was made to check it in Activity_Create, all of my code does this in Restore instead.

Everything seems to work fine but I was wondering what issues this can cause if I leave it all in the Restore?
 
Status
Not open for further replies.
Top