• AS3 CookBook学习整理(十四)


    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 _detectedBandNumber;
     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);

  • 相关阅读:
    Java编程基础
    Python开发【第十四篇】:Python操作MySQL
    MySQL(二)
    MySQL(一)
    Python之路【第五篇】:面向对象及相关
    Python开发【第四篇】:Python基础之函数
    Python开发【第三篇】:Python基本数据类型
    等保测评备案流程?备案资料有哪些?
    xls/csv文件转换成dbf文件
    csv 转换为DBF文件的方法
  • 原文地址:https://www.cnblogs.com/CoderWayne/p/1778079.html
Copyright © 2020-2023  润新知