X

操作子SWF(五)覆盖原则

当项目已经很是久远,当资源又管理不善,丢失源文件的情况终于发生了.当我们需要修改它的时候却发现fla和as文件找不到了,重新写一个又要好长时间,而且只需要做简单的修改,比如添加Event.ADDED_TO_STAGE后再访问stage属性.这时覆盖原则就派上用场了,但是不到万不得以的时候还是不要使用为妙,因为会增加维护成本.

流程

  1. 如果没有源代码了,就用反编译软件将AS类反编译出来,这里只需要AS代码,素材不需要.
  2. 在主SWF里创建一个与要修改的子SWF里类的完全限定名一致的类(例如SubSWF.as),并修改相应的代码.
  3. 在MainSWF里引用到类SubSWF(不仅仅是import).
  4. MainSWF加载原来的SubSWF.swf.
  5. 加载完成后就能看到SubSWF.swf的行为已经改变在MainSWF里的SubSWF.as的行为了.

简单代码

在SubSWF.swf里的SubSWF.as类

package  
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    public class SubSWF extends Sprite
    {
        public function SubSWF()
        {
            // 旧代码在未添加到显示列表就访问stage对象,必定会报错
            stage.addEventListener(MouseEvent.CLICK, clickHandler);
        }
        public function clickHandler(e:MouseEvent):void
        {
            trace("this is clickHandler!");
        }
    }
}

在MainSWF里新写的SubSWF.as类

package  
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    public class SubSWF extends Sprite
    {
        public function SubSWF()
        {
            // 新代码在添加到显示列表后,再访问stage对象,就不会报错了
            addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.addEventListener(MouseEvent.CLICK, clickHandler);
        }
        public function clickHandler(e:MouseEvent):void
        {
            trace("this is clickHandler!");
        }
    }
}

MainSWF加载的代码

// 首先引导新的SubSWF类,以保证能到编译进来,这很重要
SubSWF;

// 说明要加载的子swf的文件路径
var req:URLRequest = new URLRequest("subSwf.swf");
var loader:Loader = new Loader();
// 一定要用loder.contentLoaderInfo添加侦听,不然不会触发COMPLETE事件
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.load(req);

function completeHandler(e:Event):void
{
    // 移除侦听,防止内存泄露
    loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, completeHandler);

    // 现在已经能看到新的SubSWF在运行了.不会再报错了.
}

结语

该方法应用了应用程序域的覆盖原则来实现的,后续我也会专门来分享覆盖原则的更多细节.

最后还是要提的是,仅在万不得以的时候才使用该方法.能不用的时候最好不要使用.当然该方法不仅仅对于文档类可用,对于在帧上写代码的同样适用,因为flash IDE会自动为其生成一个文档类,也可以对于库元件绑定的类有效,总之就是想重写哪个类就重写哪个类.

注意点:对于用Flash IDE自动生成属性的那些属性(也就是在元件的属性面板里声明的属性)一定要在重写后的类里也同样有这些public的属性.

This post was last modified on 2019 年 03 月 04 日 00:29

View Comments (1)

This website uses cookies.