我是移动应用程序开发的新手,但我正在尝试构建一个移动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%"/>
数据库.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吗?如果返回true,我是否应该调度一个事件,然后只运行跟踪语句以获得正确的长度?这似乎过于复杂,只是为了保存一些数据,所以我不完全确定发生了什么或如何修复它
无论如何,我要问的是,我当前的设置是否正确,如果不正确,是否有人有一个简单的示例,或者可以根据我的代码创建一个简单示例,说明如何正确使用persistencemanger?
一旦我掌握了这项技术,我也可以创建其他几个应用程序,所以我真的希望能把它固定下来。提前感谢!
编辑:我似乎正确地使用了关于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>
数据库.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;
}
}
}
特征VO.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导致了问题吗?
我不太熟悉使用它,但从文档来看,你可能无法使用通用对象,因为我不相信它实现了IExternalizable,根据文档,这不会因为某种原因导致错误,但它实际上无法读取/写入这些对象。
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/managers/PersistenceManager.html
使用管理器存储值时,重要的是所有值可以正确地写入共享对象。复杂的对象存储类或非标准闪存基元必须实现flash.net.Ixternalizable接口正常工作。节省物不兼容的对象不会导致RTE,但会创建未定义的对象读取回数据时的行为。
当我自己使用它时,有一次在一个项目中帮助另一位SO发布者时,我不记得真的有任何问题,除非我们更改了正在存储/检索的模型对象的属性,然后我们必须手动销毁它正在创建的本地共享对象,否则它无法对其进行反序列化(这是有道理的,但只是需要注意的一点)。我实际上不记得实现了IExternalizable,但有可能是另一个人做的。
试试这个:
[CharactVO.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会通过按顺序序列化它的所有元素来自动序列化。