as3在本地客户端提供了两个对象:LocalConnection和SharedObject本地共享对象。利用这两个对象可以弥补客户端浏览器Js的很多不足.而本地共享对象更具独有的性质,对每一个独立域的SWF来说默认都拥有100K的本地共享存储空 间.虽然只有100K但是可以做很多的事情了,例如可以用作跨域Cookie,或是用户参数设置的保存等.当看到这里的时候,不知道有没有人想到,可以将 这100K做成一个在本地加载的运行库? 在这里我们探索一下.
先解释一下什么叫本地运行库, 如果学过C的人都知道,C有一些库文件,后缀名为.lib,这些库文件里面存储的是已编译好的程序,包抱数据结构和功能函数,它是一个静态的库,当C编译 的时候加载这些库里面已编译好的二进制数据结构或函数放到目标的程序中,这样就可以实现代码重用,加快编译速度. 在C++时代,也有类似的库,但更多使用的是后缀名为.dll的库文件,.dll的库文件跟.lib的有根本性的区别. .dll的库文件叫动态库文件, 它是指程序在执行的时候加载这个.dll文件进内存再调用里面的函数,实例它里面的类. 现在我们讨论的就是在AS3中实现类似的.dll这种文件的功能. 在用户客户端浏览器中缓存一些可动态加载并运行的库类. 当然,你也可以将Js字符串放在里面,加载运行. 呵呵,听起来是不是不可思议? 你可千万不要下载一个病毒放在这里面哦,不然我想杀毒 软件都清不了. 呵呵,说笑啦,FlashPlayer的安全沙箱不允许你缓存的这个库跨域读取或执行,所以不用担心这个.
要实现本地运行库的第一个条件成熟了,就是有地方缓存,有100K供我们使用,如果有的用户设置达1M的空间,那么,你可以缓存更多的东西,不过一般的用户不会设置这么高的. 第二个条件就是如何存取一个库到这个本地共享对象中去, 我们可以采用将swf从服务器端读取出来,然后用二进制的形式写进去, 还好AS3的URLRequest提供了一个读取二进制数据的功能,而Loader也提供了一个将二进制转化为SWF的功能. 这样,本地运行库实现起来就比较简单了.
下面讲一下我的思路:
本地运行库的目的是,将一些常用的工具类,或是一些不变的资源文件打包成一个SWF文件,带一个版本号,通过URLRequest加载成功后,缓存在本地,作为一个运行支持的库,里面的类,或是图片资源等,你要的时候就去这个库取出来就可以了.示例代码如下:
package {import Flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.SharedObject;
import flash.utils.ByteArray;
import load.LoadEvent;
import load.LoadFileBase;
import load.LoadFileData;
/**
* 完成本地共享对象的读取,版本比较,加载,替换等操作.
*/
public class LocalRunLib extends Sprite{
public const LOADFAILED:String=”load_local_Lib_failed”;
public const LOADSUCCESS:String=”load_local_Lib_success”;
private var ver:String;
public var Lib:*;
public function LocalRunLib():void{
getLib(“Lib.swf”,”0708a01″);
addEventListener(LOADSUCCESS,testSuccess);
addEventListener(LOADFAILED,testFailed);
}
private function testSuccess(event:Event):void{
trace(event.target.Lib.applicationDomain.getDefinition(“Tt”));
}
private function testFailed(event:Event):void{
trace(event.target);
}
/**
* 获取运行库.
* @param _url 获取本地失败后,向远程加载.
* @param ver 当前需要的版本.
*/
private functiongetLib(_url:String,ver:String):void{
var flag:Boolean=false;
var share:SharedObject=SharedObject.getLocal(“resources”);
var Obj:Object=share.data;
this.ver=ver;
if(Obj!=null)
if(Obj.version==ver){
converToLib(Obj.lib);
flag=true;
}
share.close();
share=null;
if(!flag){
var loadFile:LoadFileBase=new LoadFileBase(newLoadFileData(_url,LoadFileBase._SWF));
loadFile.addEventListener(LoadFileBase.SUCCESS,success);
loadFile.addEventListener(LoadFileBase.FAILED,failed);
}
}
/**
* 将共享对象变成可运行的库.
*/
private function _onLoaderComplete(event:Event):void{
// 下面的Lib大伙可以测试一下,是否是Loader对象了.
Lib=event.currentTarget;
event.target.removeEventListener(Event.COMPLETE,_onLoaderComplete);
dispatchEvent(new Event(LOADSUCCESS));
}
/**
* 写入到库.
*/
private function writeLocalLib(swf:*,ver:String):*{
var share:SharedObject=SharedObject.getLocal(“resources”);
share.data.version=ver;
share.data.lib=swf;
share.flush();
share.close();
share=null;
}
/***
* 将二进制内容转化为可运行库.
*/
private function converToLib(data:ByteArray):void{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,_onLoaderComplete);
loader.loadBytes(data);
}
/**
* 加载指定url的运行库成功.
*/
private function success(event:LoadEvent):void{
converToLib(event.loadData.data as ByteArray);
writeLocalLib(event.loadData.data,ver);
removeEvent(event.target as LoadFileBase);
}
/**
* 加载指定url的运行库失败.
*/
private function failed(event:LoadEvent):void{
removeEvent(event.target as LoadFileBase);
dispatchEvent(new Event(LOADFAILED));
}
/**
* 删除事件.
*/
private function removeEvent(loadFile:LoadFileBase):void{
loadFile.removeEventListener(LoadFileBase.SUCCESS,success);
loadFile.removeEventListener(LoadFileBase.FAILED,failed);
}
}
}