>>在未看下面内容之前,做个评价
Flex框架代码太难看懂了。
各个类之间的关系错总复杂。这样的结构设计是情非得已还是没有经过认真的审核?
>>正文
当SystemManager监听到主程序(Application)、RSL、资源文件都下载完毕后,将FlashPlayer播放头向前推进一帧,这时候,会走到名为“kickOff”的函数体内。
该函数将负责实例化主程序(Application)。
SystemManager.as
mx_internal function kickOff():void
{
……
//这里将动态生成几个类对象,并调用它们的函数:init()
var mixinList:Array = info()["mixins"];
if (mixinList && mixinList.length > 0)
{
var n:int = mixinList.length;
for (var i:int = 0; i < n; ++i)
{
……
var c:Class = Class(getDefinitionByName(mixinList[i]));
c["init"](this);
……
}
}
//实例化Application
initializeTopLevelWindow(null);
……
}
上面代码中的info()["mixins"]是些什么呢?
查看编译器生成的中间as代码,可以发现其中有一个名称为_XXXX_mx_managers_SystemManager-generated.as 的文件。
其中定义了mixins代表的类名。本例中是两个类。
"_test_FlexInit"指的是_XXXX_FlexInit-generated.as 的文件。
override public function info():Object
{
if (!_info)
{
……
_info = {
mixins: [ "_test_FlexInit", "_test_Styles" ],
……
}
}
查看编译器生成的中间as代码,可以发现其中有一个名称为_XXXX_FlexInit-generated.as 的文件,其init()函数内容为:
_XXXX_FlexInit-generated.as
public static function init(fbs:IFlexModuleFactory):void
{
new ChildManager(fbs);
……
}
ChildManager又是什么呢?
mx.managers.systemClasses.ChildManager.as
public function ChildManager(systemManager:IFlexModuleFactory)
{
super();
if (systemManager is ISystemManager)
{
//将自己存入SystemManager中,这样,能访问到SystemManager实例的地方就可以访问到ChildManager
systemManager["childManager"] = this;
……
}
}
这ChildManager是什么东西呢?
好了,再回头看SystemManager的kickOff函数中后面调用的initializeTopLevelWindow函数,它使用了ChildManager:
SystemManager.as
private function initializeTopLevelWindow(event:Event):void
{
……
childManager.initializeTopLevelWindow(w, h);
}
mx.managers.systemClasses.ChildManager.as
public function initializeTopLevelWindow(width:Number, height:Number):void
{
……
//生成Application实例
systemManager.document = app = topLevelWindow = IUIComponent(systemManager.create());
……
}
systemManager.create()找到了吗?
通过反射我们获得了["mainClassName"]所代表的Application实例
SystemManager.as
public function create(... params):Object
{
var mainClassName:String = info()["mainClassName"];
if (mainClassName == null)
{
var url:String = loaderInfo.loaderURL;
var dot:int = url.lastIndexOf(".");
var slash:int = url.lastIndexOf("/");
mainClassName = url.substring(slash + 1, dot);
}
var mainClass:Class = Class(getDefinitionByName(mainClassName));
return mainClass ? new mainClass() : null;
}
info()["mainClassName"]是什么?
查看编译器生成的中间as代码,可以发现其中有一个名称为_XXXX_mx_managers_SystemManager-generated.as 的文件。
【mainClassName: "test"】是因为我们用的示例代码的主程序名称是test。
override public function info():Object
{
if (!_info)
{
……
_info = {
mainClassName: "test",
……
}
}