您的位置:首页 > 其它

AS3 CookBook学习整理(十四)

2010-07-15 15:23 295 查看
1. 清除视频显示

调用Video对象的clear()方法

在调用netStream.close()以后,并不会自动清除video显示的内容。视频的最后一帧内容仍显示在Video对象上,需调用video.clear()来进行清除

要从现实列表上删除Video对象需调用removeChild(video)

2. 检测用户带宽

Flash播放器并没有内建带宽检测系统,要想测出用户带宽,需要通过Flash播放器下载一个文件(如JPEG文件),通过下载的大小和所花的时间可以计算出平均下载速度,根据8个比特等于1个字节,1000个字节等于1个kilobyte(kb),转换公式为:

kilobits(KB) = bytes /1000 * 8;

package {
import flash.display.Sprite;
import flash.events.Event;
public class Sample0625 extends Sprite
{
public function Sample0625()
{
var bandwidthTester:BandwidthTest = new BandwidthTest( );
bandwidthTester.addEventListener(Event.COMPLETE, onBandwidthTest);
bandwidthTester.test( );
}

private function onBandwidthTest(event:Event):void
{
trace(event.target.detectedBandwidth);
}
}
}
import flash.events.EventDispatcher
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.utils.getTimer;
internal class BandwidthTest extends EventDispatcher
{
private var _downloadCount:uint;
private var _bandwidthTests:Array;
private var _detectedBandwidth:Number;
private var _startTime:uint;

public function BandwidthTest()
{
_downloadCount = 0;
_bandwidthTests = new Array( );
}

public function get detectedBandwidth( ):Number
{
return _detectedBandwidth;
}

// Run the bandwidth test.
public function test( ):void
{
// Use a URLLoader to load the data.
var loader:URLLoader = new URLLoader( );
// Use a URL with a unique query string to ensure the data  is
// loaded from the server and not from browser cache.
var request:URLRequest = new URLRequest("Test.jpg?unique=" + (new Date( )).getTime( ));
loader.load(request);
loader.addEventListener(Event.OPEN, onStart);
loader.addEventListener(Event.COMPLETE, onLoad);
}

// When the file starts to download get the current timer value.
private function onStart(event:Event):void
{
_startTime = getTimer( );
}

private function onLoad(event:Event):void
{
// The download time  is  the timer value when the file has downloaded
// minus the timer value when the value started downloading. Then
// divide by 1000 to convert from milliseconds to seconds.
var downloadTime:Number = (getTimer( ) - _startTime) / 1000;
_downloadCount++;
// Convert from bytes to kilobits.
var kilobits:Number = event.target.bytesTotal / 1000 * 8;
// Divide the kilobits by the download time.
var kbps:Number = kilobits / downloadTime;
// Add the test value to the array.
_bandwidthTests.push(kbps);
if(_downloadCount == 1)
{
// If it's only run one test then run the second.
test( );
}
else if(_downloadCount == 2)
{
// If it's run two tests then determine the margin between the
// first two tests.
// If the margin  is  small ( in  this example, less than 50 kbps)
// then dispatch a complete event. If not run a test.
if(Math.abs(_bandwidthTests[0] - _bandwidthTests[1]) < 50)
{
dispatchCompleteEvent( );
}
else
{
test( );
}
}
else
{
// Following the third test dispatch a complete event.
dispatchCompleteEvent( );
}
}

private function dispatchCompleteEvent( ):void
{
// Determine the avarage bandwidth detection value.
_detectedBandwidth = 0;
var i:uint;
for(i = 0; i < _bandwidthTests.length; i++)
{
_detectedBandwidth += _bandwidthTests[i];
}
_detectedBandwidth /= _downloadCount;
// Dispatch a complete event.
dispatchEvent(new Event(Event.COMPLETE));
}
}

3. 使用SharedObject存储信息

ActionScript中,SharedObject类实现了客户端机器数据的持久性存储。有两种类型的共享对象:本地和远程

本地 -- Local Shared Objects(LSOs)

远程 -- Remote Shared Objects(RSOs)

Flash的LSOs就如同Web浏览器中的cookies,它们被一些开发者称为"超级cookies",因为LSOs可以存储大量数据,且存储和读取的都是原生的ActionScript数据类型

LSOs默认的空间大小100KB,用户可以通过Flash Player's Settings Manager控制LSOs的使用空间大小。存储在客户端的LSO文件是一种二进制文件,扩展名为.sol,同一个域的Flash电影通过flash.net.SharedObject类读写.sol文件

当.sol文件创建后,被放置在Flash播放器对应的应用程序数据目录

Windows XP:
For Web sites -- C:\Documents and Settings\<user>\Application Data\Macromedia\Flash Player
\#SharedObjects\<random code>\<domain>\<path>\<object name>.sol
For AIR Applications -- C:\Documents and Settings\<user>\Application Data\<AIR Application Reverse Domain Name>
\Local Store\#SharedObjects\<flash filename>.swf\<object name>.sol

Windows Vista/2008:
C:/Users/username/<user>/AppData/Roaming/Macromedia/Flash Player/#SharedObjects/<domain>/<path>
/<flash filename>.swf/<object name>.sol

SharedObject类的静态方法getLoal()用于创建或打开共享对象,它至少需要一个参数指明共享对象名称:

var example:SharedObject = SharedObject.getLocal("myOption");

getLocal()方法首先试图定位找到LSO,如果找不到则根据这个名字创建新的,否则就返回SharedObject实例

SharedObjects对象有个内建的属性data,data属性类型为object,因此可以添加任何信息(不能存储可视化对象,如Sprite,TextFields)

package {
import flash.display.Sprite;
import flash.net.SharedObject;
public class Sample0625 extends Sprite
{
public function Sample0625()
{
var shareObj:SharedObject = SharedObject.getLocal("myOption");
shareObj.data.name = "hxw";
shareObj.data.gameList = new Array("wow","war3","dota");
shareObj.data.loginTime = new Date();
shareObj.data.newObj = {age:"23",city:"shenzhen",msn:null};
}
}
}

4. 保存SharedObject对象(Flush)

以下几种情况会导致Flash自动试图保存LSO数据到硬盘上:

* 当Flash播放器关闭时

* 当SharedObject对象被垃圾回收时

* 当调用SharedObject.clear()、SharedObject.close()方法时

如果需要立即保存共享对象数据,我们可以显式调用SharedObject.flush()方法:

var flushResult:String = sharedObject.flush(minDiskSpace)

参数minDiskSpace为必须分配给此对象的最小磁盘空间,单位为字节,默认为0

当flush()方法触发时,它试图把数据写到客户端上,调用结果有三种(flushResult的返回值):

SharedObjectFlushStatus.FLUSHED -- 成功保存

SharedObjectFlushStatus.PENDING -- 显示对话框,要求用户增加磁盘空间量以供此域中的对象使用

抛出Error -- 用户拒绝存储或Flash播放器因某种原因导致存储失败

PS: 为了避免返回PENDING,请为minDiskSpace传递一个值

package {
import flash.display.Sprite;
import flash.events.NetStatusEvent;
import flash.net.SharedObject;
import flash.net.SharedObjectFlushStatus;
public class Sample0625 extends Sprite
{
private var example:SharedObject;

public function Sample0625()
{
example = SharedObject.getLocal("example");
example.data.someData = "a value";

var flushResult:String = "";

try
{
flushResult = example.flush( );
if ( flushResult == SharedObjectFlushStatus.PENDING )
{
//当用户做出选择后,netStatus事件被激活,需要定义一个事件处理函数,当事
//件处理函数被触发时,传递进一个类型为flash.events.NetStatusEvent的事件,
//检查info.code属性值判断用户是同意(SharedObject.Flush.Success)
//还是拒绝(SharedObject.Flush.Failed)
example.addEventListener( NetStatusEvent.NET_STATUS, onStatus );
}
else if ( flushResult == SharedObjectFlushStatus.FLUSHED )
{
//存储成功
}
}
catch ( e:Error )
{
//这里代表用户的本地存储设置为'Never',可以在这里弹出一个设置框让用户修改
//Security.showSettings( SecurityPanel.LOCAL_STORAGE );
}
finally
{
trace(example.data.someData);
trace(flushResult);
}
}

private function onStatus(event:NetStatusEvent):void
{
if (event.info.code == "SharedObject.Flush.Success" )
{
//用户选择了同意
}
else if (event.info.code == "SharedObject.Flush.Failed" )
{
//用户选择了拒绝
}
//只需要监听一次,所以移除掉该事件监听
example.removeEventListener( NetStatusEvent.NET_STATUS, onStatus );
}
}
}

5. 删除SharedObject里保存的数据

用delete删除data集合中的某个属性,或使用clear()方法清除整个共享对象(即删除了.sol文件)

package {
import flash.display.Sprite;
import flash.net.SharedObject;
public class Sample0626 extends Sprite
{
public function Sample0626()
{
var obj:SharedObject = SharedObject.getLocal("jay");
obj.data.name = "hxw";
obj.data.pwd = "millfox";
obj.data.game = "wow";

for(var str1:String  in  obj.data)
{
trace(str1 + ":" + obj.data[str1]);
}

delete obj.data.pwd;
trace("----------------------");

for(var str2:String  in  obj.data)
{
trace(str2 + ":" + obj.data[str2]);
}

obj.clear();
trace("----------------------");

for(var str3:String  in  obj.data)
{
trace(str3 + ":" + obj.data[str3]);
}
}
}
}
将会输出:
name:hxw
game:wow
pwd:millfox
----------------------
name:hxw
game:wow
----------------------
6. 使用SharedObject存储自定义类实例

LSOs使用特殊的二进制格式,Action Message Format(AMF),当要在LSO中存储类实例时,实例会被编码为包含属性的普通的object。这样当重新从共享对象中读取实例时,已经不是原来的类实例了,因为已不能根据类型信息解码回来

解决方法是调用flash.net.registerClassAlias("classAliasName",ClassName)

package {
import flash.display.Sprite;
import flash.net.SharedObject;
import flash.net.registerClassAlias;
public class Sample0703 extends Sprite
{
public function Sample0703()
{
registerClassAlias("hxw.class.person",Person);

var shareObj:SharedObject = SharedObject.getLocal("userInfo");

if(shareObj.data.person == undefined)
{
var obj:Person = new Person("胡晓伟",27);
shareObj.data.person = obj;
}
else
{
delete shareObj.data.person;
}

trace(shareObj.data.person  is  Person);
//trace(shareObj.data.person.toString());
}
}
}
internal class Person
{
private var _name:String;
private var _age:int;

public function Person(name:String,age:int)
{
_name = name;
_age = age;
}

public function toString():String
{
return _name + "  is  " + _age + " years old";
}
}

7. swf文件之间共享LSO数据

默认情况下,LSOs存储的名称是唯一的,这主要是为了防止名称冲突(不同swf生成的sol文件,会在以这个swf命名的文件夹下)

如果要让同一个域中的多个swf文件能访问同一个LSO,可以指定SharedObject.getLocal("example","/")的第二个参数

package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.SharedObject;
import flash.text.TextField;
public class Sample0703 extends Sprite
{
private var shareObj:SharedObject;
private var textBox:TextField;

public function Sample0703()
{
shareObj = SharedObject.getLocal("clickRate","/");

if(shareObj.data.clickNumber == undefined)
{
shareObj.data.clickNumber = 0;
}

textBox = new TextField();
this.addChild(textBox);
stage.addEventListener(MouseEvent.CLICK,onClick);
}

private function onClick(event:MouseEvent):void
{
shareObj.data.clickNumber += 1;
textBox.text = shareObj.data.clickNumber;
}
}
}

8. 让用户设置LSO的空间大小

使用Security.showSettings(SecurityPanel.LOCAL_STORAGE)弹出对话框,让用户自定义大小

9. 同一台电脑的多个swf文件通信(LocalConnection)

分为发送端(Send)和接收端(Receive)

发送端LocalConnection.send("_myChannel", 'receiveMethod');

接收端LocalConnection.connect("_myChannel");

若不想在send()方法中指定域名,但要向Flash Player指出接收方和发送方LocalConnection对象不在同一个域中,可在connect()和send()调用中的连接名之前加一个下划线"_",这样Flash Player不会加入域信息,如果不是以下划线开头,则通信信道名称字符串将被自动转换成domain:connectionName,而不管是本地域还是远程域

同一个域

// receivingLC  is  in  http://www.domain.com/receiving.swf receivingLC.connect('myConnection');
// sendingLC  is  in  http://www.domain.com/sending.swf // myMethod()  is  defined  in  sending.swf
sendingLC.send('myConnection', 'myMethod');

具有可预知域名的不同域

// receivingLC  is in  http://www.domain.com/receiving.swf receivingLC.allowDomain('www.anotherdomain.com');
receivingLC.connect('myConnection');
// sendingLC  is  in http://www.anotherdomain.com/sending.swf sendingLC.send('www.domain.com:myConnection', 'myMethod');

具有不可预知域名的不同域

// receivingLC  is  in  http://www.domain.com/receiving.swf receivingLC.allowDomain('*');
receivingLC.connect('_myConnection');
// sendingLC  is  in  http://www.anotherdomain.com/sending.swf sendingLC.send('_myConnection', 'myMethod');

发送端代码:

package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.StatusEvent;
import flash.net.LocalConnection;
public class MySender extends Sprite
{
public function MySender()
{
stage.addEventListener(MouseEvent.CLICK,onClick);
}

private function onClick(event:MouseEvent):void
{
var localConn:LocalConnection = new LocalConnection();
localConn.send("_myChannel","showGame","World Of Warcraft");
localConn.addEventListener(StatusEvent.STATUS,onStatus);
}

private function onStatus(event:StatusEvent):void
{
trace(event.level);
}
}
}

接收端代码

package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.LocalConnection;
import flash.text.TextField;
public class MyReceiver extends Sprite
{
private var textBox:TextField;
private var localConn:LocalConnection;

public function MyReceiver()
{
textBox = new TextField();
this.addChild(textBox);

stage.addEventListener(MouseEvent.CLICK,onClick);
}

private function onClick(event:MouseEvent):void
{
localConn = new LocalConnection();
localConn.allowDomain("*");
localConn.connect("_myChannel");
localConn.client = this;
}

public function showGame(str:String):void
{
textBox.text = str;
}
}
}

PS: 还有个与allowDomain( )类似的方法allowInsecureDomain( )方法,大多数情况下这两种方法是一样,不同点在于HTTPS的使用上,当flash来自于HTTPS,其里面的本地连接实例不能和来自于HTTP的flash通信,除非使用allowInsecureDomain( ),默认下HTTP 和HTTPS 的flash是不能通信的,即使是在同一个域。并不推荐使用allowInsecureDomain( ),这样可能会带来不安全因素

10. Loader与URLLoader的区别

Loader -- 读取swf、图片(jpg、png、gif)

URLLoader -- 文本文件(xml、php、jsp...)

Loader加载过来的数据类型:

如果加载图片文件(jpg,gif,png等)时,Loader.content得到数据类型是Bitmap对象;

如果加载SWF文件(flash 9 版本)时,Loader.content得到数据类型是MovieClip对象;

如果加载SWF文件(flash 9 以前版本) 时, Loader.content得到数据类型是AVM1Movie对象;

Loader是给它的contentLoaderInfo属性增加事件,而不是给Loader对象增加事件:

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);

URLLoader是给它自己增加事件:

xmlLoader.dataFormat=URLLoaderDataFormat.TEXT;

xmlLoader.addEventListener(Event.COMPLETE,xmlLoaded);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: