您的位置:首页 > 其它

flash AS3 Loader加载外部文件类 及队列加载方法

2018-03-31 10:53 399 查看
从2011年开始使用这段代码为了应对各种加载修修改改了这么多年,很基础的功能,没啥特别的,重点在于加载子swf获取它的类,还有就是卸载子swf时要清理内存,否则内存占用会节节窜高,内存溢出,所以加载新swf文件时要提前 .clear(); 没啥特别的,重点是loader.unloadAndStop(); loader.unload(); 不过注意的是音视频文件是清理不掉的,需要在子swf里写脱离场景侦听进行卸载音视频各类监听事件。
加载进来的文件默认是子域,ApplicationDomain分子域、共享域、封装域,三个的区别就不详细赘述了。
ClassLoader.as :package cn.flashme.loading{
/*
================================================================================

《加载SWF文件Loading...》

来源网络
------------------------------------------------------------
Copyright (c) 2011 [无空]

My web:
闪耀空间 http://www.flashme.cn/ E-mail:
flashme@live.cn
2011-11-18
================================================================================

构造函数:

public function ClassLoader(obj:Object = null,lc:LoaderContext = null)
参数1可以是字符串,可以是ByteArray,如果为前者则采用load方法Methods,后者采用loadBytes方法Methods
参数2是创建带有指定 LoaderContext 对象得ClassLoader实例,LoaderContext 可以设置是否加载跨域文件,应用程序域等,详见官方LoaderContext类讲解!

load 方法Methods:

public function load(_url:String,lc:LoaderContext = null):void
加载文件
参数1是加载地址,参数2见构造函数

loadBytes 方法Methods

public function loadBytes(bytes:ByteArray,lc:LoaderContext = null):void
加载字节文件
参数1是字节数据,参数2见构造函数

getClass 方法Methods

public function getClass(className:String):Object
获取一个公共定义,可以是类,也可以是命名空间或者函数定义
参数1是获取class得完整包加类名,例如偶们得这个类完整定义名称是 index.base.net.ClassLoader
详见例子

hasClass 方法Methods:

public function hasClass(className:String):Boolean
返回是否含有该公共定义
参数1见getClass方法Methods

clear 方法Methods

public function clear():void
清空

url 属性:

public var url:String
获取url属性

loader 属性:

public var loader:Loader
获取loader属性

例子1:

一个虚拟人物形象得动作包,其中包含了8种不同得动作
在使用ClassLoader加载这个swf得动作包后,即可使用getClass来调用这些素材,并且可以重复得new这些元件,来达到多次重复使用

例子2:
将设偶有一个类库,有这么三个类

然后把它编译成swf

----------------------------------------------示例:

一:

import cn.flashme.loading.ClassLoader;

var cl:ClassLoader = new ClassLoader;
cl.load("main.swf");

cl.addEventListener(Event.COMPLETE,fun);
function fun(e:Event){
var tmp1 = cl.getClass("index.base.net.ByteLoader");
trace(tmp1)

var tmp2 = cl.getClass("index.base.net.ClassLoader");
trace(tmp2)

var tmp3 = cl.getClass("index.base.geom.Dot");
trace(tmp3)
}

* trace得结果:
* [class ByteLoader]
* [class ClassLoader]
* [class Dot]

二:

import cn.flashme.loading.ClassLoader;

var cl:ClassLoader = new ClassLoader;
cl.load("main.swf");

cl.addEventListener(Event.COMPLETE,fun);
function fun(e:Event){
var tmp = cl.getClass("drag");
addChild(new tmp);
}

*/
import flash.display.Loader;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.system.LoaderContext;

public class ClassLoader extends EventDispatcher {

public var url:String;
public var loader:Loader;
public var id:String;

//构造函数
public function ClassLoader(obj:Object=null,lc:LoaderContext=null) {
if (obj!=null) {
if (obj is ByteArray) {
loadBytes(obj as ByteArray,lc);
} else if (obj is String) {
load(obj as String,lc);
} else {
throw new Error("参数错误,构造函数第一参数只接受ByteArray或String");
}
}
}

//加载
public function load(_url:String,lc:LoaderContext=null):void {
url=_url;
loader=new Loader ;
loader.load(new URLRequest(url),lc);
addEvent();
}

//加载字节
public function loadBytes(bytes:ByteArray,lc:LoaderContext=null):void {
loader=new Loader ;
loader.loadBytes(bytes,lc);
addEvent();
}

//开始侦听
private function addEvent():void {
loader.contentLoaderInfo.addEventListener(Event.OPEN,openFun);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,progressFun);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeFun);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorFun);
}

//结束侦听
private function delEvent():void {
loader.contentLoaderInfo.removeEventListener(Event.OPEN,openFun);
loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,progressFun);
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,completeFun);
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,errorFun);
}

//加载开始
private function openFun(e:Event):void {
dispatchEvent(e);
}

//加载成功,发布成功事件
private function completeFun(e:Event):void {
delEvent();
dispatchEvent(e);
}

//加载过程
private function progressFun(e:ProgressEvent):void {
dispatchEvent(e);
}

//加载失败
private function errorFun(e:IOErrorEvent):void {
delEvent();
dispatchEvent(e);
}

//获取定义
public function getClass(className:String):Object {
return loader.contentLoaderInfo.applicationDomain.getDefinition(className);
}

//是否含有该定义
public function hasClass(className:String):Boolean {
return loader.contentLoaderInfo.applicationDomain.hasDefinition(className);
}

//清除
public function clear():void {
if(loader){
delEvent();
loader.unloadAndStop();//卸载子swf 以及内部的事件侦听移除 关闭流
loader.unload();
loader=null;
}
}
}
}
后期又自己扩展了个队列加载,那时候做了个电子书,100多张图片不可能同时加载,会慢死,所以要从第一页开始向后加载,而两张两张的同时加载是效率最高的,不传数值的话默认是2张同时加载。
功能包含按id提取对象文件,按数目提取,按id或数目清除特定文件,及清理所有对象文件
LoadAll.as :
package cn.flashme.loading{
/*
================================================================================

《多文件队列加载》

支持文件:jpg/png/gif/bmp/swf
ClassLoader基础上的队列加载,不需要时可及时清理对象,清理swf对象基本上完美垃圾回收,特殊对象如声音仍需手动在被加载flash里执行卸载清理!

------------返回侦听:
全部加载完毕的侦听是"onCompleteAll"
加载进程中的侦听是"onProgressAll"
加载比率调用Rate
单独文件加载侦听可外部ClassLoader定义,也可LoadAll内get函数调用ClassLoader定义

------------注:
正反排序true优先级是数字越小越优先,false是数字越大越优先,id推荐是唯一的值。
若有多个相同地址文件,而后需要调用,建议赋予id。

------------方法:
//(同时加载进程,正反排序)推荐同时加载为2会下载快些
var LoadQueue:LoadAll=new LoadAll(2,false);
//(地址,ClassLoader,唯一id,优先级,加载域)
LoadQueue.addLoad("pic1.png",null,0);
LoadQueue.addLoad("main.swf",null,1,0,new LoaderContext(false,ApplicationDomain.currentDomain));
LoadQueue.addLoad("pic2.jpg",null,2,1);
LoadQueue.Start();
------------------------------------------------------------
Copyright (c) 2012 [无空]

My web:
闪耀互动 http://www.flashme.cn/ E-mail:
flashme@live.cn
2012-12-10
================================================================================
*/
//import flash.display.Loader;
//import flash.net.URLRequest;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.system.LoaderContext;
import cn.flashme.loading.ClassLoader;

public class LoadAll extends EventDispatcher {

//加载队列数组
public var Queue:Array=[];
//加载比率
public var Rate:Number;
//加载完成的数量
private var loadNum:uint;
//正序排列或倒序排列
private var turn:Boolean;
//同时加载进程数量
private var same:uint;
//最新加载数值位置
private var nowNum:uint;
//加载进程结束的数量
private var overNum:uint;

public function LoadAll(num:uint=2,_turn:Boolean=true):void {
same = num;
turn = _turn;
}

//(地址,ClassLoader,优先级,唯一id,加载域)
public function addLoad(url:String,_loader:ClassLoader=null,id:String="",pr:int=0,lc:LoaderContext=null):void {

var loader:ClassLoader;
if(_loader){
loader = _loader;
}else{
loader = new ClassLoader();
}
loader.id=id;
Qu
a364
eue.push({Loader:loader,Url:url,Pr:pr,Lc:lc});

}

//加载队列开始
public function Start():void {
Sort();
same=same>Queue.length?Queue.length:same;
nowNum=same-1;
for(var i:uint=0;i<same;i++){
Queue[i].Loader.load(Queue[i].Url,Queue[i].Lc);
Queue[i].Loader.addEventListener(ProgressEvent.PROGRESS,onProgressLoader);
Queue[i].Loader.addEventListener(IOErrorEvent.IO_ERROR,onErrorLoader);
Queue[i].Loader.addEventListener(Event.COMPLETE,onCompleteLoader);
}
}

//用文件地址来获取,若有相同文件,只读取排在后面的!
public function getUrl(str:String):ClassLoader {
for (var i:int = Queue.length - 1; i >= 0; i--) {
if(Queue[i].Url==str){
return Queue[i].Loader;
}
}
return null;
}

//用ID来获取,若有相同文件,只读取排在后面的!
public function getId(str:String):ClassLoader {
for (var i:int = Queue.length - 1; i >= 0; i--) {
if(Queue[i].Loader.id==str){
return Queue[i].Loader;
}
}
return null;
}

//获取排序
public function getOrder(loader:ClassLoader):int {
for(var k in Queue){
if(Queue[k].Loader==loader){
return k;
}
}
return -1;
}

//按文件地址清除文件,若有相同文件,都会被执行清除!
public function clearUrl(str:String):Boolean {
var boo:Boolean=false;
for (var i:int = Queue.length - 1; i >= 0; i--) {
if(Queue[i].Url==str){
Queue[i].Loader.clear();
Queue[i].Loader=null;
Queue.splice(i,1);
boo=true;
}
}
return boo;
}

//按id清除文件,有相同id只清除最后一个
public function clearId(str:String):Boolean {
for (var i:int = Queue.length - 1; i >= 0; i--) {
if(Queue[i].Loader.id==str){
Queue[i].Loader.clear();
Queue[i].Loader=null;
Queue.splice(i,1);
return true;
}
}
return false;
}

//清除所有加载对象
public function clearAll():void {
for(var k in Queue){
Queue[k].Loader.clear();
Queue[k].Loader=null;
}
Queue=null;
Queue=[];
}

//加载侦听:
private function onProgressLoader(e:ProgressEvent):void {
var percent:Number=(e.bytesLoaded/e.bytesTotal)/Queue.length;
Rate=(loadNum+percent)/Queue.length;
dispatchEvent(new Event("onProgressAll"));
}
private function onCompleteLoader(e:Event):void{
trace("完成一个")
loadNum++;
e.target.removeEventListener(IOErrorEvent.IO_ERROR,onErrorLoader);
e.target.removeEventListener(Event.COMPLETE,onCompleteLoader);
e.target.removeEventListener(ProgressEvent.PROGRESS,onProgressLoader);
nextLoad();
}
private function onErrorLoader(e:IOErrorEvent):void{
trace("错误一个",e)
loadNum++;
e.target.removeEventListener(IOErrorEvent.IO_ERROR,onErrorLoader);
e.target.removeEventListener(Event.COMPLETE,onCompleteLoader);
e.target.removeEventListener(ProgressEvent.PROGRESS,onProgressLoader);
nextLoad();
}

private function nextLoad():void {
if(nowNum<Queue.length-1){
nowNum++;
}else{
overNum++;
if(overNum==same){
trace("全部加在完毕")
Rate=1;
dispatchEvent(new Event("onCompleteAll"));
}
return;
}
Queue[nowNum].Loader.load(Queue[nowNum].Url,Queue[nowNum].Lc);
Queue[nowNum].Loader.addEventListener(IOErrorEvent.IO_ERROR,onErrorLoader);
Queue[nowNum].Loader.addEventListener(Event.COMPLETE,onCompleteLoader);
Queue[nowNum].Loader.addEventListener(ProgressEvent.PROGRESS,onProgressLoader);
}
//数组冒泡排序,Pr对比排列
private function Sort():void {
var temp:Object;
for (var i:uint=0; i<Queue.length; i++) {
for (var j:uint=Queue.length-1; j > i; j--) {

if (turn==true ? Queue[j - 1].Pr > Queue[j].Pr : Queue[j - 1].Pr < Queue[j].Pr) {
temp = Queue[j - 1];
Queue[j - 1] = Queue[j];
Queue[j] = temp;
}

}
}

}

}

}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息