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;
{ flash.display.Sprite; flash.events.Event; Sample0625Sprite { Sample0625() { bandwidthTester:BandwidthTest = BandwidthTest( ); bandwidthTester.addEventListener(Event.COMPLETE, onBandwidthTest); bandwidthTester.test( ); } onBandwidthTest(event:Event): { (event.target.detectedBandwidth); } } } flash.events.EventDispatcher flash.net.URLLoader; flash.net.URLRequest; flash.events.Event; flash.utils.getTimer; BandwidthTestEventDispatcher { _downloadCount:uint; _bandwidthTests:Array; _detectedBandwidth:Number; _startTime:uint; BandwidthTest() { _downloadCount = 0; _bandwidthTests = Array( ); } get detectedBandwidth( ):Number { _detectedBandwidth; } test( ): { loader:URLLoader = URLLoader( ); request:URLRequest = URLRequest( + (Date( )).getTime( )); loader.load(request); loader.addEventListener(Event.OPEN, onStart); loader.addEventListener(Event.COMPLETE, onLoad); } onStart(event:Event): { _startTime = getTimer( ); } onLoad(event:Event): { downloadTime:Number = (getTimer( ) - _startTime) / 1000; _downloadCount++; kilobits:Number = event.target.bytesTotal / 1000 * 8; kbps:Number = kilobits / downloadTime; _bandwidthTests.push(kbps); (_downloadCount == 1) { test( ); } else (_downloadCount == 2) { (Math.abs(_bandwidthTests[0] - _bandwidthTests[1]) < 50) { dispatchCompleteEvent( ); } else { test( ); } } else { dispatchCompleteEvent( ); } } dispatchCompleteEvent( ): { _detectedBandwidth = 0; i:uint; (i = 0; i < _bandwidthTests.length; i++) { _detectedBandwidth += _bandwidthTests[i]; } _detectedBandwidth /= _downloadCount; dispatchEvent(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)
{ flash.display.Sprite; flash.net.SharedObject; Sample0625Sprite { Sample0625() { shareObj:SharedObject = SharedObject.getLocal(); shareObj.data.name = ; shareObj.data.gameList = Array(,,); shareObj.data.loginTime = Date(); shareObj.data.newObj = {age:,city:,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传递一个值
{ flash.display.Sprite; flash.events.NetStatusEvent; flash.net.SharedObject; flash.net.SharedObjectFlushStatus; Sample0625Sprite { example:SharedObject; Sample0625() { example = SharedObject.getLocal(); example.data.someData = ; flushResult:String = ; { flushResult = example.flush( ); if ( flushResult == SharedObjectFlushStatus.PENDING ) { example.addEventListener( NetStatusEvent.NET_STATUS, onStatus ); } else if ( flushResult == SharedObjectFlushStatus.FLUSHED ) { } } ( e:Error ) { } finally { (example.data.someData); (flushResult); } } onStatus(event:NetStatusEvent): { if (event.info.code == ) { } else if (event.info.code == ) { } example.removeEventListener( NetStatusEvent.NET_STATUS, onStatus ); } } }
5. 删除SharedObject里保存的数据
用delete删除data集合中的某个属性,或使用clear()方法清除整个共享对象(即删除了.sol文件)
{ flash.display.Sprite; flash.net.SharedObject; Sample0626Sprite { Sample0626() { obj:SharedObject = SharedObject.getLocal(); obj.data.name = ; obj.data.pwd = ; obj.data.game = ; (str1:String obj.data) { (str1 + + obj.data[str1]); } delete obj.data.pwd; (); (str2:String obj.data) { (str2 + + obj.data[str2]); } obj.clear(); (); (str3:String obj.data) { (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)
{ flash.display.Sprite; flash.net.SharedObject; flash.net.registerClassAlias; Sample0703Sprite { Sample0703() { registerClassAlias(,Person); shareObj:SharedObject = SharedObject.getLocal(); (shareObj.data.person == undefined) { obj:Person = Person(,27); shareObj.data.person = obj; } else { delete shareObj.data.person; } (shareObj.data.person Person); } } } Person { _name:String; _age:int; Person(name:String,age:int) { _name = name; _age = age; } toString():String { _name + + _age + ; } }
7. swf文件之间共享LSO数据
默认情况下,LSOs存储的名称是唯一的,这主要是为了防止名称冲突(不同swf生成的sol文件,会在以这个swf命名的文件夹下)
如果要让同一个域中的多个swf文件能访问同一个LSO,可以指定SharedObject.getLocal("example","/")的第二个参数
{ flash.display.Sprite; flash.events.MouseEvent; flash.net.SharedObject; flash.text.TextField; Sample0703Sprite { shareObj:SharedObject; textBox:TextField; Sample0703() { shareObj = SharedObject.getLocal(,); (shareObj.data.clickNumber == undefined) { shareObj.data.clickNumber = 0; } textBox = TextField(); .addChild(textBox); stage.addEventListener(MouseEvent.CLICK,onClick); } onClick(event:MouseEvent): { 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.connect('myConnection'); sendingLC.send('myConnection', 'myMethod');
具有可预知域名的不同域
receivingLC.allowDomain('www.anotherdomain.com'); receivingLC.connect('myConnection'); sendingLC.send('www.domain.com:myConnection', 'myMethod');
具有不可预知域名的不同域
receivingLC.allowDomain('*'); receivingLC.connect('_myConnection'); sendingLC.send('_myConnection', 'myMethod');
发送端代码:
{ flash.display.Sprite; flash.events.MouseEvent; flash.events.StatusEvent; flash.net.LocalConnection; MySenderSprite { MySender() { stage.addEventListener(MouseEvent.CLICK,onClick); } onClick(event:MouseEvent): { localConn:LocalConnection = LocalConnection(); localConn.send(,,); localConn.addEventListener(StatusEvent.STATUS,onStatus); } onStatus(event:StatusEvent): { (event.level); } } }
接收端代码
{ flash.display.Sprite; flash.events.MouseEvent; flash.net.LocalConnection; flash.text.TextField; MyReceiverSprite { textBox:TextField; localConn:LocalConnection; MyReceiver() { textBox = TextField(); .addChild(textBox); stage.addEventListener(MouseEvent.CLICK,onClick); } onClick(event:MouseEvent): { localConn = LocalConnection(); localConn.allowDomain(); localConn.connect(); localConn.client = this; } showGame(str:String): { 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);