public final class AppState

  1. Object
  2. AppState

ImplementsExternalizable

A snapshot of where the user was and what they were doing: the route stack, plus whatever your StateProvider chose to add.

The same value serves three purposes, which is why it carries more than the two halves above. It is written to storage so the app can come back after its process dies; it is advertised to the user’s other devices so one of them can continue the work; and it travels through a StateRelay to devices the platform cannot reach on its own. The deviceId, sequence and timestamp are what let the receiving side tell a state it has already seen – or its own echo – from one worth acting on.

The routes

getRoutes() is the com.codename1.router.Navigation stack as a list of paths, oldest first. Restoring it re-runs each path through the route table, which is why an app that navigates with @Route gets its screens back for free and one that calls new MyForm().show() does not: those navigations are not URL-addressable, so there is nothing to write down. Such an app restores from the payload instead.

The payload

getPayload() is yours. It has to survive being written to disk, handed to an operating system and delivered to a different device running a possibly different build of your app, so it is restricted to values that mean the same thing everywhere: String, Integer, Long, Double, Boolean, and List and Map of those. Anything else is refused when the state is built, with a message naming the offending key, rather than being dropped somewhere the failure cannot be traced back here.

Constructors

public AppState()

Methods

public List<String> getRoutes()The navigation stack as route paths, oldest first.
public AppState setRoutes(List<String> r)Replaces the route paths.
public Map<String, Object> getPayload()The application payload.
public AppState setPayload(Map<String, Object> p)Replaces the application payload.
public String getDeviceId()The device this state was produced on.
public AppState setDeviceId(String id)Sets the originating device id.
public String getTitle()A human readable label for what the user is doing, which a receiving device may show before they accept the continuation.
public AppState setTitle(String t)Sets the human readable label.
public long getSequence()A counter that increases with every state this device publishes.
public AppState setSequence(long s)Sets the sequence number.
public long getTimestamp()When this state was produced, as milliseconds since the epoch on the producing device.
public AppState setTimestamp(long t)Sets the production timestamp.
public boolean isEmpty()True when there is nothing here worth restoring or sending.
public String toString()Returns a string representation of the object.
public int getVersion()Returns the version for the current persistance code, the version will be pased to internalized thus allowing the internalize method to recognize classes persisted in older revisions
public String getObjectId()The object id must be unique, it is used to identify the object when loaded even when it is obfuscated.
public void externalize(DataOutputStream out) throws IOExceptionAllows us to store an object state, this method must be implemented in order to save the state of an object
public void internalize(int version, DataInputStream in) throws IOExceptionLoads the object from the input stream and allows deserialization

Inherited methods

Constructor details

AppState

public AppState()

Method details

getRoutes

public List<String> getRoutes()
The navigation stack as route paths, oldest first. Never null, possibly empty.

Returns

an unmodifiable view of the route paths

setRoutes

public AppState setRoutes(List<String> r)
Replaces the route paths.

Parameters

r List<String>
the paths, oldest first; null is treated as empty

Returns

this state, for chaining

getPayload

public Map<String, Object> getPayload()

The application payload. Never null, possibly empty.

The view is unmodifiable ALL THE WAY DOWN. Wrapping only the outer map left every nested List and Map mutable, which matters most for an arrival: the same AppState handed to a listener or a provider is afterwards parked, persisted, acknowledged and published, so a caller that consumed a nested list – removing items as it applied them, which is an ordinary way to write that loop – changed the framework’s own snapshot of what arrived. setPayload() deep-copies on the way in for exactly this reason; the way out needed to match.

Returns

an unmodifiable view of the payload

setPayload

public AppState setPayload(Map<String, Object> p)
Replaces the application payload.

Parameters

p Map<String, Object>
the payload; null is treated as empty

Returns

this state, for chaining

Throws

IllegalArgumentException
when a value cannot cross to another device

getDeviceId

public String getDeviceId()
The device this state was produced on. Used to drop a state’s own echo when it comes back through a relay. Never null.

Returns

the originating device id

setDeviceId

public AppState setDeviceId(String id)
Sets the originating device id.

Parameters

id String
the id; null is treated as the empty string

Returns

this state, for chaining

getTitle

public String getTitle()
A human readable label for what the user is doing, which a receiving device may show before they accept the continuation. Null when the app did not set one.

Returns

the title, or null

setTitle

public AppState setTitle(String t)
Sets the human readable label.

Parameters

t String
the title, or null for none

Returns

this state, for chaining

getSequence

public long getSequence()
A counter that increases with every state this device publishes. Together with the device id it identifies a state exactly, which is how a receiver recognizes one it has already acted on – two states can share a timestamp, because clocks are coarse.

Returns

the sequence number

setSequence

public AppState setSequence(long s)
Sets the sequence number.

Parameters

s long
the sequence number

Returns

this state, for chaining

getTimestamp

public long getTimestamp()

When this state was produced, as milliseconds since the epoch on the producing device.

Treat it as advisory. It comes from another device’s clock, so it is only as trustworthy as that clock: it can be behind, ahead, or – across a daylight saving change or a manual correction – both within one session.

Returns

the timestamp

setTimestamp

public AppState setTimestamp(long t)
Sets the production timestamp.

Parameters

t long
milliseconds since the epoch

Returns

this state, for chaining

isEmpty

public boolean isEmpty()
True when there is nothing here worth restoring or sending.

Returns

true when both the routes and the payload are empty

toString

public String toString()
Returns a string representation of the object. In general, the toString method returns a string that “textually represents” this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@’, and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + ‘@’ + Integer.toHexString(hashCode())

getVersion

public int getVersion()
Returns the version for the current persistance code, the version will be pased to internalized thus allowing the internalize method to recognize classes persisted in older revisions

Returns

version number for the persistant code

getObjectId

public String getObjectId()
The object id must be unique, it is used to identify the object when loaded even when it is obfuscated.

Returns

a unique id

externalize

public void externalize(DataOutputStream out) throws IOException
Allows us to store an object state, this method must be implemented in order to save the state of an object

Parameters

out DataOutputStream
the stream into which the object must be serialized

Throws

java.io.IOException
the method may throw an exception

internalize

public void internalize(int version, DataInputStream in) throws IOException
Loads the object from the input stream and allows deserialization

Parameters

version int
the version the class returned during the externalization processs
in DataInputStream
the input stream used to load the class

Throws

java.io.IOException
the method may throw an exception