overriding-default-mx-managers(翻译)

参考地址:

http://segfaultlabs.com/blog/post/overriding-default-mx-managers

PROBLEM SUMMARY

在Flex/AIR程序中自定义各种managers ,比如改变PopUpManager弹出窗口的方式。

SOLUTION SUMMARY

文章将介绍怎样在Application启动时改变标准的manager的实现方式,而不改变managers的正常用法(在程序中我们依然使用mx.managers.*包下的类)。我们也不用为改变某个manager类而重构所有的代码。

EXPLANATION

一般的做法是自定义manager类并在使用manager时使用自定义的类而不是默认的manager类。拿PopUpManager举例,如果想自定义addPopup方法,一般做法是新建一个类,比如叫PopManager,之后在该使用PopUpManager类时使用PopManager类。这样我们只需继承默认的manager类,并调用默认类的所有方法,而不用重构所有的代码。

在进一步的讨论中,我们还是拿PopUpManager举例。PopUpManager所有的公开方法都是静态的,在其内部,它使用mx.core.PopUpManagerImpl(实现了IPopUpManager接口)的实例处理各种弹出窗口。实现类存储在mx.core.Singleton类中。所有的managers类的实现类都在程序启动时由SystemManager在mx.core.Singleton注册,一个manager类只能有一种实现类。mx.core.Singleton使用registerClass方法来注册这些单实例的实现类。注册的原则是使用先注册的类(first in wins),之后注册的类将被忽略。所以如果我们想使用自定义的manager类,必须在SystemManager注册默认的类之前行动。SystemManager的注册过程在SystemManager.mx_internal::docFrameHandler方法中实现,该方法在Application实例化之前被调用。

最好的(看起来也是唯一的)重写框架manager类实现的方法就是实现IPreloaderDisplay接口,使用该接口注册自定义的manager类。IPreloaderDisplay接口的实现类DownloadProgressBar用于在 Flex/AIR程序加载时显示进度条。我们可以使用Application的preloader属性重新为它赋值。SystemManager会在注册manager实现类之前创建和实例化Preloader,因此我们重写IPreloaderDisplay接口的initialize方法。

package my.domain {
 public class MyPreloader extends DownloadProgressBar
 {
   override public function initialize():void
   {
     super.initalize();
     Singleton.registerClass("mx.core.IPopUpManager",
                             Class( my.domain.managers.MyPopUpManager ) );
   };
 } 
}

现在调用PopUpManager的静态方法时就会调用自定义的IPopUpManager实现类的方法,下面是例子,

package my.domain.managers {
  public function MyPopUpManager extends PopUpManagerImpl
 {
   private var instance : IPopUpManager;

   static public function getInstance():IPopUpManager
   {
       if ( !instance ) instance = new MyPopUpManager();
     return instance;
   };

   override public function addPopUp( ... ):void
   {
     super.addPopUp(...);
    /* custom code */
   }

 }
}

注意自定义类需实现getInstance静态方法,该方法会在Singleton注册时调用。使用同样的方法,下列manager类也可以重写(但不是所有的manager都可以重写)。
BrowserManager
CursorManager
HistoryManager
LayoutManager
ToolTipManager
DragManager

例子