共享对象在flex - Mobile中无法正常工作

时间:2012-04-11 07:31:04

标签: actionscript-3 flex

我有一个非常简单的测试,使用移动设备在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相同。

1 个答案:

答案 0 :(得分:3)

问题的根源在于您尝试将实例MovieClip保存到SharedObject中。由于MovieClip是一个内部对象(Flash的原生对象),因此无法将其转换为可以存储的形式。这会导致flash将数据转换为存储在磁盘上的通用Object。我现在只能猜测究竟是什么进入了SharedObject。

它似乎第一次工作,因为flash实际上并没有在getPeople()调用中加载共享对象,它只使用已经在内存中的对象。应用程序第二次运行时,它从磁盘读取通用对象并创建一个通用对象。

还有一个问题是flash播放器在读取对象时不知道将数据传递给构造函数。

有一些可能的解决方法,其中一些是:

  • 将数据存储为文本
  • 将数据存储为ByteArray
  • 将数据存储在“数据对象”

在读取和写入过程中,每个都需要进行一些转换,但这可以使用接口进行简化。这也增加了对象更改的灵活性,您仍然可以读取SharedObject中的数据。

1:文字

例如,您可以向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方法,以获得将对象与文本串行化的一致方法。

2:ByteArray

非常类似于上面描述的文本方法,除了serialise / deserialise方法将接受ByteArray的附加参数,该对象将写入该参数。然后将保存ByteArray并从共享对象加载。这种方法的优点是结果数据通常比文本方法紧凑和通用。

Flash还定义了IDataInputIDataOutput接口,可以在这里使用。

3:数据对象

如果您仍然喜欢直接存储对象,那么您可以创建一个代理对象,其唯一目的是承载数据。数据对象(又称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使用保存和加载的类的相同版本。

希望有所帮助。