Flex 优化技巧 -- 全局CSS样式模块实现RSLS 方式加载

阅读更多

小记:

   

   时隔3年游戏开发后又回到了Flex的开发上面来。虽然现在的Flex的热度已经大不如以前,甚至到了Flex SDK 4.7 版本Adobe Flash Builder 干脆连设计试图都不支持了。如今的Flex SDK, 4.6, 4.7 已经和之前大不一样了。比如之前的滚动的处理实现,CSS样式域的问题,现如今都得到了一一支持。但是不管怎么样Flex SDK 的优越性在目前市面上所有的Flash UI FrameWork中,他们都是无法比拟的。

 

 再次接触Flex sdk 发现还是有点不尽人意的地方,比如在主题样式和资源这块。在project Compile Option中加入-keep-generated-actionscript 参数时会在项目的bin文件下生成对应的Actionscript代码。如下图:

 

 


Flex 优化技巧 -- 全局CSS样式模块实现RSLS 方式加载_第1张图片

 

其中包含了默认的Locale 资源和 默认的Theme 资源。 

 

对于Locale 资源我们可以在project Compile Option 加入 -locale, 这样默认的一套Locale Resource就可以做成ResourceModual 了, 而且是可以RSls加载支持的。

 

但是对于Defualt Theme 这块是去不掉的, 如果每个Project都一样的花,这个有点浪费资源了,虽然不大到目前为止(除掉Locale Resource)一个空的Project 大概38K。

 

对于Local 的资源我的构想是 Default Local Resource Modual + Custom Defined Local Resource Modual

对于样式这块的资源我的构想是 defualt Theme Modual + Global CSS Style Modual + Custom CSS Style Modual

 

对于样式这块,采用Rsls方式去实现,估计是不可能的,可以去看下生成的代码。不但是这样,就连我想加一个全局样式模块都不可以。

 

大概能使用的就是,在Application 中 使用styleManager.loadStyleDeclarations()去加载了,或者在Custom Preload Bar中去加载,但是不管怎么样,一定是在Application初始化后才能做的。

下面我来介绍一中方式,大概和Rsls类似的效果,而且是在New Application 之前发生的。 但是,为什么一定要纠结在 new Appication 之前,因为运行时切换皮肤是很耗资源的能不要这样做就不要这样做。

 

 

看下实现过程:

 

 

package com.citi.crm.flex
{
	import flash.display.DisplayObject;
	import flash.events.IEventDispatcher;
	import flash.events.ProgressEvent;
	
	import mx.core.IFlexModuleFactory;
	import mx.core.mx_internal;
	import mx.events.StyleEvent;
	import mx.managers.ISystemManagerChildManager;
	import mx.managers.systemClasses.ChildManager;
	import mx.styles.IStyleManager2;

	use namespace mx_internal;
	
	[Mixin]
	public class FakeChildManager implements ISystemManagerChildManager
	{
		private static var _instance:FakeChildManager;
		private static var _styleURL:String;
		
		public static function init(fbs:IFlexModuleFactory):void
		{
//			_styleURL = "ClientInsightCRM_GlobalStyle.swf";
			_styleURL = Object(fbs).loaderInfo.parameters.gStyleURL;
			if(_styleURL)
			{
				//for hold the instance
				_instance = new FakeChildManager(fbs);
			}
		}
		
		private var _systemManager:Object;
		private var _realChildManager:ISystemManagerChildManager;
		private var _styleLoadWatcher:IEventDispatcher;
		
		public function FakeChildManager(systemManager:IFlexModuleFactory)
		{
			super();
			
			_systemManager = systemManager;
			
			_realChildManager = _systemManager["childManager"]; 
			_systemManager["childManager"] = this;
		}
		
		//ISystemManagerChildManager Interface
		public function initializeTopLevelWindow(width:Number, height:Number):void
		{
			//just complete initializeTopLevelWindow function instead in hakc way.
			doOurLoadingFlow();
		}
		
		protected function doOurLoadingFlow():void
		{
			var styleManager:Object = _systemManager.getImplementation("mx.styles::IStyleManager2");
			
			_styleLoadWatcher = IEventDispatcher(Object(styleManager).loadStyleDeclarations(_styleURL, false));
			
			_styleLoadWatcher.addEventListener(StyleEvent.PROGRESS, gStyleProgressHandler);
			_styleLoadWatcher.addEventListener(StyleEvent.COMPLETE, gStyleCompleteHandler);
			_styleLoadWatcher.addEventListener(StyleEvent.ERROR, gStyleErrorHandler);
		}
		
		protected function onDoOurLoadingFlowEnd():void
		{
			_styleLoadWatcher.removeEventListener(StyleEvent.PROGRESS, gStyleProgressHandler);
			_styleLoadWatcher.removeEventListener(StyleEvent.COMPLETE, gStyleCompleteHandler);
			_styleLoadWatcher.removeEventListener(StyleEvent.ERROR, gStyleErrorHandler);
			_styleLoadWatcher = null;
			
			_systemManager["childManager"] = _realChildManager;
			
			_realChildManager.initializeTopLevelWindow(_systemManager.width, _systemManager.height);
			
			_realChildManager = null;
			_systemManager = null;
			_instance = null;
			_styleURL = null;
		}
		
		public function addingChild(child:DisplayObject):void {};
		public function childAdded(child:DisplayObject):void {};
		
		public function childRemoved(child:DisplayObject):void {};
		public function removingChild(child:DisplayObject):void {};
		
		//event handler
		private function gStyleProgressHandler(event:StyleEvent):void
		{
			IEventDispatcher(_systemManager.preloader).dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS,
				false, false, event.bytesLoaded, event.bytesTotal));
		}
		
		private function gStyleCompleteHandler(event:StyleEvent):void
		{
			onDoOurLoadingFlowEnd();
		}
		
		private function gStyleErrorHandler(event:StyleEvent):void
		{
			//just skip it
			onDoOurLoadingFlowEnd();
		}
	}
}

 

一定 需要将此类引用到项目中,不然不会作用的。

 

Mixin 元标签是保证,在new Application 之前调用 public static function init(fbs:IFlexModuleFactory):void 执行代码。而且在构造函数里面我们偷偷换掉了SystemManager 中的ChildManager的引用对象,改为当前,

因为我们就是要阻止实际的ChildManager的initializeTopLevelWindow()函数的执行, 在FakeChildManager 的initializeTopLevelWindow,

我们来做自己的事情,等完成后在把SystemManager 中的ChildManager引用换成原来真实的ChildManager 对象, 并调用initializeTopLevelWindow。

 

 

 

这种方式我认为是最简洁的实现Css modual Rsls 的加载方式。 你们有什么好办法?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

  • Flex 优化技巧 -- 全局CSS样式模块实现RSLS 方式加载_第2张图片
  • 大小: 138.6 KB
  • 查看图片附件

你可能感兴趣的:(Flex 优化技巧 -- 全局CSS样式模块实现RSLS 方式加载)