[url]http://bbs.9ria.com/viewthread.php?tid=76876&extra=page%3D1%26amp%3Borderby%3Ddateline%26amp%3Bfilter%3D2592000[/url]
嵌入式资源
另一个常用功能就是嵌入外部资源(XML或者Pixel Bender Kernel 滤镜)时会用到.我们经常会碰到的问题就是将那些运行时依赖的资源嵌入到外部swf中.一些服务端拒绝swf拥有外部依赖(external dependency),所以假设你开发了一个小型的应用或游戏并且在几分钟后你需要快速的删除所有外部依赖(external dependency),你可以使用Embed标签来实现这一功能.
在下面的代码中,我们使用Embed标签来嵌入一个外部的 Pixel Bender 滤镜
在编译时, Pixel Bender 滤镜将被当做一个ByteArray嵌入,注意mimeType application/octet-stream的用途就是允许嵌入资源被当做ByteArray.
更一般的我们也可以将XML作为嵌入资源:
任何东西都可以通过这种方法嵌入,我们通过bytearray的API来操作这里嵌入的原始二进制数据 .但需要强调的是上一段代码有一点冗余,所以我们可以通过使用特定的mimeType,来强制的要求转码器将其映射为特定的类型.在下列的代码中,你会看到同样的嵌入使用mimeType后代码变得极其简单.
很便捷吧?接下来让我们来了解一下怎么样在运行时注入和重建bytes的内容.Adobe Flash Player 提供了一个非常强大的API来处理这种情景.
注入bytes
一般来说注入的对象可以是图像,字体,甚至是swf.Flash player 中没有SWF类型,但是你猜怎么着?Loader对象的API中有一个loadBytes.
这就是允许我们将swf当做一个ByteArray注入到Loader对象中并可以运行它:
为了显示它,我们只需要将Loader添加到显示列表即可:
复制代码
对于图像或者声音,你甚至不需要设定mimeType.转码器不需要任何干预就可以自动将stream映射成正确的类型.
让我们再深入了解一下图像,在下面的部分我们将会用一种新的方法来动态加载图像.
图像的渐进式加载
Flash player中另一个和byte相关的强大API叫做:URLStream,这个API允许我们在FLash player中下载东西并可以访问已下载的内容.其形式如同一个由服务器推送数据的soket一样.
让我们来看下面的代码:
我们可以看到 ProgressEvent.PROGRESS 事件被广播了多次,Event.COMPLETE 事件在结束时被广播了一次.
但是当一些数据被下载后你的确是可以通过loader发送给你的数据来访问他们.在这一过程中你还以通过一个对象得知当前已加载量和总加载量.
让我们在前一段代码的基础上做一些修改.
现在我们会将当前已加载的字节以字符串的形式读取出.你应该会在output窗口看到原始google页面的html代码.如下所示:
这就意味着我们的逐步的读取字节.这一有趣的特点造就了我们的下一个实例,在加载完毕前通过尽快的解析图像(字节)中的头部(head)信息来重现图像.
我们通过API loadBytes来显示接收到的数据,当我们插入新的字节数据时,FLash Player显示出了其内容.下图展示出了一张未加载完的图像.
然后图像逐步显示直至最终加载完成
现在你可能不太清楚其真正的价值,但是这一实例的确很好的告知了我们可以用URLStream接收到的数据来干什么.就像我们刚刚看到的,loadBytes是一个非常强大的API但是它也有自身的限制.在接下来的部分我们将去探寻为什么有些时候开发者被其困住了.
Loadbytes 的局限性
要记住loadBytes是异步的,所以需要我们需要等到Event.COMPLETE事件之后才可以读取swf的大小,class定义等.下面的代码说明了这一大意:
只有当加载完毕后类定义才可以被获取到:
在loader对象中的所有种类的文件都必遵从这个限制.有很多开发者企图在加载过程中动态读取一个图像,但是在我们现有的RSL(动态运行时共享库)机制下,图像相关数据的读取必须要等到加载完毕后才可以进行,并且图像的解析是由Flash player进行的:
因此你也需要一个异步的处理方法.在加载过程中你需要手动的来解析.为此我用 adobe的 Alchemy 写过一个动态的JPEG解码器 (http://www.bytearray.org/?p=1089)
嵌入式资源
另一个常用功能就是嵌入外部资源(XML或者Pixel Bender Kernel 滤镜)时会用到.我们经常会碰到的问题就是将那些运行时依赖的资源嵌入到外部swf中.一些服务端拒绝swf拥有外部依赖(external dependency),所以假设你开发了一个小型的应用或游戏并且在几分钟后你需要快速的删除所有外部依赖(external dependency),你可以使用Embed标签来实现这一功能.
在下面的代码中,我们使用Embed标签来嵌入一个外部的 Pixel Bender 滤镜
[Embed(source="myFilter.pbj", mimeType="application/octet-stream")]
var myShaderKernel:Class;
在编译时, Pixel Bender 滤镜将被当做一个ByteArray嵌入,注意mimeType application/octet-stream的用途就是允许嵌入资源被当做ByteArray.
更一般的我们也可以将XML作为嵌入资源:
import flash.utils.ByteArray;
[Embed(source="test.xml", mimeType="application/octet-stream")]
var xmlStream:Class;
// instanciate the stream as a ByteArray
var xmlBytes:ByteArray = new xmlStream();
// read the XML String from the byte stream
var xmlString:String = xmlBytes.readUTFBytes( xmlBytes.bytesAvailable );
// instanciate a XML object by passing the content
var myXML:XML = new XML(xmlString);
/*
outputs :
<menu>
<item/>
<item/>
<item/>
</menu>
*/
trace ( myXML );
// outputs : 3
trace ( myXML.item.length() );
任何东西都可以通过这种方法嵌入,我们通过bytearray的API来操作这里嵌入的原始二进制数据 .但需要强调的是上一段代码有一点冗余,所以我们可以通过使用特定的mimeType,来强制的要求转码器将其映射为特定的类型.在下列的代码中,你会看到同样的嵌入使用mimeType后代码变得极其简单.
import flash.utils.ByteArray;
[Embed(source="test.xml", mimeType="text/xml")]
var xmlStream:Class;
// instanciate a XML object by passing the content
var myXML:XML = new XML (xmlStream.data);
/*
outputs :
<menu>
<item/>
<item/>
<item/>
</menu>
*/
trace ( myXML );
// outputs : 3
trace ( myXML.item.length() );
很便捷吧?接下来让我们来了解一下怎么样在运行时注入和重建bytes的内容.Adobe Flash Player 提供了一个非常强大的API来处理这种情景.
注入bytes
一般来说注入的对象可以是图像,字体,甚至是swf.Flash player 中没有SWF类型,但是你猜怎么着?Loader对象的API中有一个loadBytes.
这就是允许我们将swf当做一个ByteArray注入到Loader对象中并可以运行它:
import flash.utils.ByteArray;
import flash.display.Loader;
[Embed(source="test-loading.swf", mimeType="application/octet-stream")]
var swfStream:Class;
// instanciate the stream as a ByteArray
var swfBytes:ByteArray = new swfStream();
// instanciate a Loader
var myLoader:Loader = new Loader();
// inject the embedded stream inside the Loader
// the SWF is executed automatically
myLoader.loadBytes(swfBytes);
为了显示它,我们只需要将Loader添加到显示列表即可:
import flash.utils.ByteArray;
import flash.display.Loader;
[Embed(source="test-loading.swf", mimeType="application/octet-stream")]
var swfStream:Class;
// instanciate the stream as a ByteArray
var swfBytes:ByteArray = new swfStream();
// instanciate a Loader
var myLoader:Loader = new Loader();
// show the Loader object
addChild ( myLoader );
// inject the embedded stream inside the Loader
// the SWF is executed automatically What can you do with bytes ? – Chapter 2 – Everyday bytes
myLoader.loadBytes(swfBytes);
复制代码
对于图像或者声音,你甚至不需要设定mimeType.转码器不需要任何干预就可以自动将stream映射成正确的类型.
import flash.utils.ByteArray;
import flash.display.Bitmap;
[Embed(source="ferrari-demo.png")]
var myImageStream:Class;
// instanciate the image as a classic Bitmap instance
var myImage:Bitmap = new myImageStream();
// show it!
addChild ( myImage );
让我们再深入了解一下图像,在下面的部分我们将会用一种新的方法来动态加载图像.
图像的渐进式加载
Flash player中另一个和byte相关的强大API叫做:URLStream,这个API允许我们在FLash player中下载东西并可以访问已下载的内容.其形式如同一个由服务器推送数据的soket一样.
让我们来看下面的代码:
// creates a URLStream object
var stream:URLStream = new URLStream();
// listen to the ProgressEvent.PROGRESS event to grab the incoming bytes
stream.addEventListener ( ProgressEvent.PROGRESS, onProgress );
stream.addEventListener ( Event.COMPLETE, onComplete );
// download the google.com index page
stream.load ( new URLRequest ("http://www.google.com" ) );
function onProgress ( e:ProgressEvent ):void
{
trace ("progress");
}
function onComplete ( e:Event ):void
{
trace ("complete");
}
我们可以看到 ProgressEvent.PROGRESS 事件被广播了多次,Event.COMPLETE 事件在结束时被广播了一次.
但是当一些数据被下载后你的确是可以通过loader发送给你的数据来访问他们.在这一过程中你还以通过一个对象得知当前已加载量和总加载量.
让我们在前一段代码的基础上做一些修改.
现在我们会将当前已加载的字节以字符串的形式读取出.你应该会在output窗口看到原始google页面的html代码.如下所示:
<!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-
1"><title>Google</title><script>window.google={kEI:"xTp8TZq4HpPWtQOd4Kz4Ag",kEXPI:"28479,28501,28595,29014,291
35,29265,29279",kCSI:{e:"28479,28501,28595,29014,29135,29265,29279",ei:"xTp8TZq4HpPWtQOd4Kz4Ag",expi:"28479,28
501,28595,29014,29135,29265,29279"},ml:function(){},kHL:"en",time:function(){return(new
Date).getTime()},log:function(c,d,
b){var a=new Image,e=google,g=e.lc,f=e.li;a.onerror=(a.onload=(a.onabort=function(){delete
g[f]}));g[f]=a;b=b||"/gen_204?atyp=i&ct="+c+"&cad="+d+"&zx="+google.time();a.src=b;e.li=f+1},lc:[],li:0,Toolbe
lt:{}…
这就意味着我们的逐步的读取字节.这一有趣的特点造就了我们的下一个实例,在加载完毕前通过尽快的解析图像(字节)中的头部(head)信息来重现图像.
// creates a URLStream object
var stream:URLStream = new URLStream();
// listen to the ProgressEvent.PROGRESS event to grab the incoming bytes
stream.addEventListener ( ProgressEvent.PROGRESS, onProgress );
stream.addEventListener ( Event.COMPLETE, onComplete );
// download the remote image
stream.load ( new URLRequest ("http://dl.dropbox.com/u/7009356/IMG_4958.jpg" ) );
// store the incoming bytes
var buffer:ByteArray = new ByteArray();
// Loader to display the picture
var loader:Loader = new Loader();
// show it
addChild ( loader );
function onProgress ( e:ProgressEvent ):void
{
// we keep writing the bytes coming in
stream.readBytes ( buffer, buffer.length );
// we clear the previously loaded content
loader.unload();
// we inject the bytes to display the image
loader.loadBytes ( buffer );
}
function onComplete ( e:Event ):void
{
trace ("complete");
}
我们通过API loadBytes来显示接收到的数据,当我们插入新的字节数据时,FLash Player显示出了其内容.下图展示出了一张未加载完的图像.
然后图像逐步显示直至最终加载完成
现在你可能不太清楚其真正的价值,但是这一实例的确很好的告知了我们可以用URLStream接收到的数据来干什么.就像我们刚刚看到的,loadBytes是一个非常强大的API但是它也有自身的限制.在接下来的部分我们将去探寻为什么有些时候开发者被其困住了.
Loadbytes 的局限性
要记住loadBytes是异步的,所以需要我们需要等到Event.COMPLETE事件之后才可以读取swf的大小,class定义等.下面的代码说明了这一大意:
import flash.utils.ByteArray;
import flash.display.Loader;
[Embed(source="library.swf", mimeType="application/octet-stream")]
var library:Class;
// instanciate the stream as a ByteArray
var swfBytes:ByteArray = new library();
// instanciate a Loader
var myLoader:Loader = new Loader();
// show the Loader object
addChild ( myLoader );
// loadBytes is asynchronous, we need to wait for the complete event before retrieving content from the loaded
SWF
myLoader.contentLoaderInfo.addEventListener ( Event.COMPLETE, onComplete );
// inject the embedded stream inside the Loader
// the SWF is executed automatically
myLoader.loadBytes(library);
// handler
function onComplete ( e:Event ):void
{
trace("loading complete");
}
只有当加载完毕后类定义才可以被获取到:
// handler
function onComplete ( e:Event ):void
{
// retrieve a class definition
var classDefinition:Class = e.currentTarget.applicationDomain.getDefinition("MyDefinition"):
}
在loader对象中的所有种类的文件都必遵从这个限制.有很多开发者企图在加载过程中动态读取一个图像,但是在我们现有的RSL(动态运行时共享库)机制下,图像相关数据的读取必须要等到加载完毕后才可以进行,并且图像的解析是由Flash player进行的:
import flash.utils.ByteArray;
import flash.display.Loader;
[Embed(source="image.jpeg", mimeType="application/octet-stream")]
var imageStream:Class;
// instanciate the stream as a ByteArray
var jpegBytes:ByteArray = new imageStream();
// instanciate a Loader
var myLoader:Loader = new Loader();
// show the Loader object
addChild ( myLoader );
// loadBytes is asynchronous, we need to wait for the complete event before retrieving image dimensions What can you do with bytes ? – Chapter 2 – Everyday bytes
myLoader.contentLoaderInfo.addEventListener ( Event.COMPLETE, onComplete );
// inject the image stream inside the Loader
myLoader.loadBytes(jpegBytes);
// handler retrieving the image size
function onComplete ( e:Event ):void
{
// outputs : width : 300 height : 400
trace ( "width : " + e.currentTarget.width, "height : " + e.currentTarget.height );
}
因此你也需要一个异步的处理方法.在加载过程中你需要手动的来解析.为此我用 adobe的 Alchemy 写过一个动态的JPEG解码器 (http://www.bytearray.org/?p=1089)