我有一个非常简单的测试,使用移动设备在flex中共享对象我有一个人类。
package
{
import flash.display.MovieClip;
public class Person extends MovieClip
{
var personsname:String="";
public function Person(name:String)
{
personsname = name;
}
}
}
然后在视图中使用一些简洁的代码。
var person1:Person;
var person2:Person;
var person3:Person;
var person4:Person;
var thePeople:Array=[];
var so:SharedObject;
function init():void{
person1 = new Person("james");
person2 = new Person("mike");
person3 = new Person("Amanda");
person4 = new Person("Shelly");
thePeople.push(person1,person2,person3,person4);
//so = SharedObject.getLocal("savedData"); //clear it again
///so.clear(); // clear it again
savePeople();
getPeople();
}
private function savePeople():void{
so = SharedObject.getLocal("savedData");
if(so.data.thePeopleArray == null){
so.data.thePeopleArray = thePeople;
so.flush();
}
}
private function getPeople():void{
so = SharedObject.getLocal("savedData");
var thePeeps:Array = so.data.thePeopleArray;
trace(thePeeps);
}
我第一次运行它时会追溯到
[object Person]
4次
我关闭模拟器并重建并运行它跟踪
,,,
如果我清除了它,那么它再次显示[object Person]
,但注释掉,,,
共享对象甚至可以正确存储对象数组。与我相信的persistanceManager相同。
答案 0 :(得分:3)
问题的根源在于您尝试将实例MovieClip保存到SharedObject中。由于MovieClip是一个内部对象(Flash的原生对象),因此无法将其转换为可以存储的形式。这会导致flash将数据转换为存储在磁盘上的通用Object。我现在只能猜测究竟是什么进入了SharedObject。
它似乎第一次工作,因为flash实际上并没有在getPeople()调用中加载共享对象,它只使用已经在内存中的对象。应用程序第二次运行时,它从磁盘读取通用对象并创建一个通用对象。
还有一个问题是flash播放器在读取对象时不知道将数据传递给构造函数。
有一些可能的解决方法,其中一些是:
在读取和写入过程中,每个都需要进行一些转换,但这可以使用接口进行简化。这也增加了对象更改的灵活性,您仍然可以读取SharedObject中的数据。
例如,您可以向Person
对象添加两个方法,将其称为serialise()
和deserialise()
。 serialise()
方法将返回可以存储在共享对象中的文本。 deserialise()
将解析文本并填充对象的值。
以下是一个示例来说明这一点:
class Person {
private var name:String;
private var age:int;
public function serialise():String {
return [name, age].join("\t");
}
public function deserialise(input:String):void {
var tokens:Array = input.split("\t");
name = tokens[0];
age = parseInt(tokens[1]);
}
public static function create(name:String, age:int):Person
{
var output:Person = new Person();
output.name = name;
output.age = age;
return output;
}
}
为了便于使用,我们可以创建一个用于管理人员集合的类:
class People {
private var people:Vector.<Person> = new Vector.<Person>();
public function clear():void {
people.splice(0, people.length);
}
public function add(person:Person):void {
people.push(person);
}
public function serialise():String {
var output:Array = [];
for each (var person:Person in people)
output.push(person.serialise());
return output.join("\n");
}
public function deserialise(input:String):void {
var tokens:Array = input.split("\n");
for each (var token:String in tokens) {
var person:Person = new Person();
person.deserialise(token);
add(person);
}
}
public function save():void {
var so:SharedObject = SharedObject.getLocal("cookie");
so.data.people = serialise();
so.flush();
}
public function load():void
{
var so:SharedObject = SharedObject.getLocal("cookie");
if (so.data.people != null)
deserialise(so.data.people);
}
}
用法:
var people:People = new People();
people.load();
trace(people.serialise());
people.clear();
people.add(Person.create("Candy", 21));
people.add(Person.create("Sandy", 23));
people.add(Person.create("Randy", 27));
people.save();
trace(people.serialise());
此示例中的一个明显缺陷是\ n和\ t字符不能用作数据的一部分(即用于人名)。这是文本数据的常见缺点。
**更新:查看内置的JSON方法,以获得将对象与文本串行化的一致方法。
非常类似于上面描述的文本方法,除了serialise / deserialise方法将接受ByteArray的附加参数,该对象将写入该参数。然后将保存ByteArray并从共享对象加载。这种方法的优点是结果数据通常比文本方法紧凑和通用。
Flash还定义了IDataInput和IDataOutput接口,可以在这里使用。
如果您仍然喜欢直接存储对象,那么您可以创建一个代理对象,其唯一目的是承载数据。数据对象(又称DO)是一个只有变量而不是方法的对象。例如:
class PersonDO {
public var name:String;
}
可以使用这样的东西:
var person2:Person;
var person3:Person;
var person4:Person;
var thePeople:Array=[];
var so:SharedObject;
function init():void{
person1 = new Person("james");
person2 = new Person("mike");
// store the people data into data objects
person1DO = new PersonDO();
person1DO.name = person1.name;
person2DO = new PersonDO();
person2DO.name = person2.name;
thePeople.push(person1DO,person2DO);
savePeople();
// load the people into data objects
getPeople();
person1 = new Person(thePeople[0].name);
person2 = new Person(thePeople[1].name);
private function savePeople():void{
so = SharedObject.getLocal("savedData");
if(so.data.thePeopleArray == null){
so.data.thePeopleArray = thePeople;
so.flush();
}
}
private function getPeople():void{
so = SharedObject.getLocal("savedData");
var thePeeps:Array = so.data.thePeopleArray;
trace(thePeeps);
}
即使这看起来比替代品更简单,但直接存储对象也存在缺点: - 存储的数据非常脆弱 - 如果更改对象,那么除非每个对象有多个版本,否则您的数据将无法使用。 - 您需要确保将对数据对象的引用编译到应用程序中。 - 共享对象的常见使用方案是从一个SWF保存数据对象,并将它们加载到另一个SWF中。您需要确保两个SWF使用保存和加载的类的相同版本。
希望有所帮助。