flash builder mobile,正确使用PersistenceManager?

时间:2012-07-31 16:04:52

标签: actionscript-3 flex mobile flash-builder persistence-manager

我是移动应用程序开发人员的新手,但我正在尝试构建一个移动RPG游戏角色表应用程序。我没有使用SQLite,而是尝试使用PersistenceManager在应用程序中断或关闭时保留字符数据,但我不确定我是否正确使用它。这是我到目前为止所拥有的。

Main.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                        xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.CharactersView" 
                        applicationDPI="160" persistNavigatorState="true">

</s:ViewNavigatorApplication>

CharactersView.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="creationCompleteHandler(event)">

<fx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.events.FlexEvent;

        protected function creationCompleteHandler(event:FlexEvent):void
        {
            var o:Object = new Object();
            o.name = "Aragorn";
            o.type = "Ranger";
            o.strength = 97;
            o.speed = 7;
            Database.insertCharacter(o);
            trace(Database.characters.length);
        }

    ]]>
</fx:Script>

<s:List id="list" width="100%" height="100%"/>

Database.as:

import spark.managers.PersistenceManager;

public class Database
{
    private static var data:Array = [];
    private static var pm:PersistenceManager = new PersistenceManager();

    public static function get characters():Array
    {
        if (!pm.load() || pm.getProperty("characters") == null)
        {
            Database.data = [];
        }
        else
        {
            Database.data = pm.getProperty("characters") as Array;
        }
        return data;
    }

    public static function insertCharacter(o:Object):void
    {
        Database.data.push(o);
        pm.setProperty("characters", Database.data);
        pm.save();
    }

}

在CharactersView.mxml的creationComplete处理程序中,我正在创建一个带有一些任意信息的一次性字符,以测试插入字符是否有效。每次我完全按原样运行它时,trace语句(我的数组的长度)返回1.每次运行它时,它不应该升一个吗?这告诉我一些事情是不对的,但持久性管理者是不是正确保存数据?我是否需要检查pm.save()是否返回true,如果是,我应该调度一个事件,然后只运行trace语句以获得正确的长度吗?这似乎过于复杂只是为了保存一些数据,所以我不完全确定最新情况或如何修复它。

在任何情况下,我问的是我的当前设置是否正确,如果不是,是否有人有一个简单的例子,或者可以根据我的代码创建一个简单的例子来说明如何正确使用persistencemanager?< / p>

一旦我掌握了这项技术,我也可以创建其他几个应用程序,所以我真的希望能够将其固定下来。提前谢谢!

编辑:我似乎正在正确使用所有关于PM的答案,我收到的答案确实帮助我让我的应用程序正常运行。但是,当我向前移动时,我的应用程例如,我的列表似乎对交互的反应非常缓慢,大多数其他组件也是如此。下面的新代码。

Main.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                        xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.CharactersView" 
                        applicationDPI="160" persistNavigatorState="true">

</s:ViewNavigatorApplication>

CharactersView.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="creationCompleteHandler(event)">

<fx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.events.FlexEvent;

        protected function creationCompleteHandler(event:FlexEvent):void
        {
            update();
        }

        private function update():void
        {
            title = "D&D Characters (" + Database.characters.length + ")";
            list.dataProvider = new ArrayCollection(Database.characters);
        }

        protected function button1_clickHandler(event:MouseEvent):void
        {
            var vo:CharacterVO = new CharacterVO();
            vo.name = "Aragorn";
            vo.className = "Ranger";
            vo.race = "Human";
            vo.level = 6;
            vo.gender = "Male";
            vo.alignment = "Unaligned";
            vo.hp = 25;
            vo.xp = 100;
            Database.insertCharacter(vo);
            update();
        }

    ]]>
</fx:Script>

<s:actionContent>
    <s:Button label="+" click="button1_clickHandler(event)"/>
</s:actionContent>

<s:List id="list" width="100%" height="100%"/>

</s:View>

Database.as:

import spark.managers.PersistenceManager;

public class Database
{
    private static var data:Array = [];
    private static var pm:PersistenceManager = new PersistenceManager();

    public static function get characters():Array
    {
        return data;
    }

    public static function insertCharacter(o:CharacterVO):void
    {
        Database.data.push(o);
        pm.setProperty("characters", Database.data);
        pm.save();

        if (!pm.load() || pm.getProperty("characters") == null)
        {
            Database.data = [];
        }
        else
        {
            Database.data = pm.getProperty("characters") as Array;
        }
    }

}

CharacterVO.as:

import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;

public class CharacterVO implements IExternalizable
{
    public var name:String;
    public var className:String;
    public var race:String;
    public var gender:String;
    public var alignment:String;
    public var level:Number;
    public var hp:Number;
    public var xp:Number;


    public function writeExternal(output:IDataOutput):void {
        output.writeUTF(name);
        output.writeUTF(className);
        output.writeUTF(race);
        output.writeUTF(gender);
        output.writeUTF(alignment);
        output.writeFloat(level);
        output.writeFloat(hp);
        output.writeFloat(xp);
    }

    public function readExternal(input:IDataInput):void {
        name = input.readUTF();
        className = input.readUTF();
        race = input.readUTF();
        gender = input.readUTF();
        alignment = input.readUTF();
        level = input.readFloat();
        hp = input.readFloat();
        xp = input.readFloat();
    }
}

正如您所看到的,大多数代码与我首次发布的代码相同。我添加了CharacterVO类,我在CharactersView.mxml中移动了一些东西,我将PersistenceManager加载代码移动到insertCharacter函数(这样,我只在每次添加新项时加载PM,而不是每次调用时Database.characters)。

同样,我的应用程序似乎对交互反应真的很慢,有时它根本没有反应。有些事情是不对的,我之前从未遇到过移动应用程序的这个问题。可能是将数组存储在PM中然后尝试将其设置为List的dataProvider会导致问题吗?

1 个答案:

答案 0 :(得分:0)

我不太熟悉使用它,但是从文档中看起来你可能不能使用通用Object,因为我不相信它实现了IExternalizable,根据文档这不会导致错误某种原因,但它实际上无法读/写这些对象。

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/managers/PersistenceManager.html

  

使用管理器存储值时,所有值都很重要   可以正确地写入共享对象。复杂的对象   存储类或非标准Flash原语必须实现   flash.net.IExternalizable接口正常工作。保存   不兼容的对象不会导致RTE,但会创建未定义的   回读数据时的行为。

当我自己使用它时,有一次在一个项目中帮助另一个SO海报我不记得确实有任何问题,除非我们更改了我们存储/检索的模型对象的属性然后我们不得不手动吹掉本地共享它正在创建的对象,否则它无法反序列化它(有意义但只是要注意的事情)。我实际上并没有记得实现IExternalizable,但是其他人可能会这样做。

试试这个:

[CharacterVO.as]

public class CharacterVO implements IExternalizable
{
    public var name:String;
    public var type:String;
    public var strength:Number;
    public var speed:Number;


    public function writeExternal(output:IDataOutput) {
        output.writeUTF(name);
        output.writeUTF(type);
        output.writeFloat(strength);
        output.writeFloat(speed);
    }

    public function readExternal(input:IDataInput) {
        name = input.readUTF();
        type = input.readUTF();
        strength = input.readFloat();
        speed = input.readFloat();
    }
}

然后,不是创建Generic对象,而是创建该VO的实例。我相信Array会通过按顺序序列化所有元素来自动序列化。