http://jacksondunstan.com/articles/1642我跟着这个到了T,但我遇到了问题。我试图保存一堆图标。他们有一个定制的班级&#34; Iconn&#34;并存储在Vector.<Iconn>
中以备将来使用。一旦用户添加了新图标,我就会打开一个文件流并用它来编写整个矢量。
public function addShortcut(f:File):void
{
//Display on side
icons.reverse(); //Add to the front so it displays on the top.
icons.push(new Iconn(f)); //Use 16x16 bitmap
addChild(icons[icons.length - 1]);
icons.reverse();
//Save object
fs = new FileStream();
fs.open(shortcuts, FileMode.WRITE);
fs.writeObject(icons);
fs.close();
reorder(); //Reorganizes the icons on the screen.
}
这一切都很好,没有任何错误,但当我尝试重新启动应用程序并保存一些图标时,矢量甚至不存在。
icons = new Vector.<Iconn>();
if (shortcuts.exists)
{
trace("Shortcuts exist..adding");
fs = new FileStream();
fs.open(shortcuts, FileMode.READ);
icons = fs.readObject() as Vector.<Iconn>;
fs.close();
trace("icons = " + icons); //TypeError: Error #1009: Cannot access a property or method of a null object reference.
trace("icons length = " + icons.length); //TypeError: Error #1009: Cannot access a property or method of a null object reference.
}
我尝试添加registerClassAlias("Vector.<Iconn>", Vector.<Iconn>);
,但后来我遇到编译错误
1067: Implicit coercion of a value of type __AS3__.vec:Vector.<Iconn> to an unrelated type Class
。
编辑:这是我的Iconn课程http://pastebin.com/5TujzpvR
答案 0 :(得分:2)
这有几个原因无效。
当对象被反序列化时,您无法将参数传递给它们的构造函数。这意味着您需要取出嵌套在对象中的所有类的所有构造函数参数,或者通过赋予它们默认值使它们全部是可选的。
您必须注册在序列化对象中使用的每个单个非基本类(包括对象的类本身)。这包括嵌套类。在您的情况下,这至少包括:
flash.display.Bitmap;
flash.display.Sprite;
flash.events.MouseEvent;
flash.filesystem.File;
fl.transitions.Tween;
fl.transitions.easing.Strong;
加上这些类中引用的任何内容。
序列化显示对象不起作用*(技术上可以使用实现IExternalizable的自定义类,但它非常复杂)。如果您想要一个示例,则有一个here。
序列化显示对象的最佳方法是创建一个非常非常基本的类,其中包含重建显示对象所需的最小数据。
在您的情况下,看起来您真正需要的只是位图数据。所以你可以创建一个简单的类,如下所示:
package
{
import flash.geom.Rectangle;
import flash.utils.ByteArray;
public class SaveData
{
public var imgBytes:ByteArray;
public var bounds:Rectangle;
public var transparent:Boolean;
}
}
它存储的全部是原始位图数据(像素值的字节数组)和位图的边界。
首先,您需要注册所有使用的类。这看起来像这样:
//you need to register your class that you're using writeObject on
registerClassAlias("SaveData", SaveData);
//you also need to register the two classes that are referenced in your SaveData class
registerClassAlias("flash.utils.ByteArray", ByteArray);
registerClassAlias("flash.geom.Rectangle", Rectangle);
//you ALSO need to register Point since it's referenced inside the Rectangle class
registerClassAlias("flash.geom.Point", Point);
现在,为了保存它,主要做你正在做的事情:
//create a vector to store your list of items to save
var saveArray:Vector.<SaveData> = new Vector.<SaveData>();
//loop through all your icons and do the following in the loop (where bitmap is the icon's bitmap):
var saveData:SaveData = new SaveData();
saveData.bounds = bitmap.getBounds(bitmap);
saveData.imgBytes = bitmap.bitmapData.getPixels(saveData.bounds);
saveData.transparent = bitmap.bitmapData.transparent;
saveArray.push(saveData);
//write the Vector to the file
fs = new FileStream();
fs.open(shortcuts, FileMode.WRITE);
fs.writeObject(saveArray);
fs.close();
现在,当你准备好把它全部加载回来时:
fs = new FileStream();
fs.open(shortcuts, FileMode.READ);
var saveArray:Vector.<SaveData> = fs.readObject() as Vector.<SaveArray>;
fs.close();
//now loop through your array and re-create all your icons.
for(var i:int=0;i<saveArray.length;i++){
var bmd:BitmapData = new BitmapData(saveArray[i].bounds.width, saveArray[i].bounds.height, saveArray[i].transparent);
bmd.setPixels(saveArray[i].bounds, saveArray[i].imgBytes);
var bitmap:Bitmap = new Bitmap(bmd);
//instead of passing in a file to your Iconn class, tweak it so you pass in a bitmap:
var icon:Iconn = new Iconn(bitmap);
//do what you need to do with he icon
}