Recipe 17.6.
Serializing Custom Classes
Problem
You want
to store an instance of a custom class in an LSO.
Solution
Use the flash.net.registerClassAlias( )
method to preserve type information and add the class instance to
the shared object's data property.
Discussion
LSOs use a special binary format, Action Message Format (AMF),
for encoding information. When you store a class instance in an
LSO, the instance is encoded as a generic object that contains
properties. Thus, when you try to read the instance back from the
shared object, it cannot be read as a class instance because it was
not encoded with type information.
To get around this limitation, the registerClassAlias( ) method from
the flash.net package is used. This method is very similar
to the Object.registerClass( ) method
used in ActionScript 1.0 and 2.0; however, Object.registerClass(
) has been removed from ActionScript 3.0 and replaced with
flash.net.registerClassAlias( ).
The registerClassAlias( ) method takes
two parameters. The first parameter is a string alias that is used to represent a
class. You can use an arbitrary string value that you want as the
alias, but the best practice is to use the fully qualified class
name. If you have a Person class in a model
package, the string alias you should use is model.Person
to provide clarity and avoid ambiguity. This approach also avoids
accidentally using a string alias multiple times, since it is
impossible to have two classes with the same fully qualified class
name. The second parameter is the reference to the class you want to map the
class alias to.
registerClassAlias( "somePackage.ExampleClass", ExampleClass );
This code tricks the LSO into storing
information about the class that created it. Therefore, when the
data is retrieved from the shared object, the Flash Player knows
what kind of object it is.
|
The custom class must have an alias registered
in any movie that retrieves the custom object data from a shared
object.
|
|
The following code example is a complete
implementation of saving an instance of a class to an LSO. First,
create a custom class to serialize.
// Create a Person class in the model package
package model {
public class Person {
private var _firstName:String;
private var _age:int;
public function Person(firstName:String, age:int) {
_firstName = firstName;
_age = age;
}
public function toString( ):String {
return _firstName + " is " + _age + " years old";
}
}
}
Next, create a main class to read and write the
data.
package {
import flash.net.registerClassAlias;
import flash.net.SharedObject;
import model.Person;
public class Example {
public function Example( ) {
// Map "model.Person" to the Person class
registerClassAlias( "model.Person", Person );
// Create a shared object and store a Person instance in it
var example:SharedObject = SharedObject.getLocal( "example" );
// Test to see if the person instance has been saved already
if ( example.data.person == undefined ) {
trace( "first time, saving person instance" );
var person:Person = new Person("Darron", 24);
// Write the class instance to the local shared object
example.data.person = person;
} else {
trace( "person instance already saved, using stored values" );
}
/* Every time this code is executed, the following is displayed:
Darron is 24 years old
*/
trace( example.data.person.toString( ) );
}
There is an important piece to point out about
the preceding code. The call to registerClassAlias( ) must
happen before the
SharedObject.getLocal( ) method call. For the shared object
to be read correctly, the class alias has to be created
before the shared object is
decoded. Creating the shared object without first creating the
alias results in the Person instance not being read;
instead, it is decoded as a generic object instead of a
class instance.
|