Frame 用于Preloader的两种方法

Frame metadata tag的本质是编译选项。

通过编译选项

AS3工程 Custom Preloader 動態加載 Application

Adobe Flex 工程的 Application 為2幀的動畫,第1幀為 Pre-load,第2幀為 Application,如果想替換 Adobe Flex 原有的 Pre-loader,那么制作將非常的方便。制作一個新的 preload Component,在 Application 的 preloader 屬性中進行相關的引用就可以完成。

這次討論的不是在 AS3 工程中直接加載 SWF,而是通過 getDefinitionByName(name:String) 的方式對 Application 進行動態加載。

例子是 Unique Instance,詳細請見 Application.as 關于 Instance 的寫法。

  • 新建ActionScript工程:PreloaderApp
  • 設定Default Application:PreloaderApp.as
  • 新建需要動態加載的主工程代碼:Application.as(不用设置为可运行程序)
  • 設置工程屬性:Properties->ActionScript Compiler->Additional compiler arguments: -frame start Application(也就是被加载的主程序)

代碼:
PreloaderApp.as

package
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.utils.getDefinitionByName;
 
	public class PreloaderApp extends MovieClip
	{
 
		/**
		 * PreloaderApp Constructor.
		 */
		public function PreloaderApp()
		{
			this.addEventListener(Event.ADDED_TO_STAGE, handleToStage);
		}
 
		/**
		 * Handle ADDED_TO_STAGE event.
		 * @param event
		 */
		private function handleToStage(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, handleToStage);
 
			//stage setting
			stage.showDefaultContextMenu = false;
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
 
			createChildren();
 
			addEventListener(Event.ENTER_FRAME, loadApplication);
 
			this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, handleProgress);
			this.loaderInfo.addEventListener(Event.COMPLETE, handleComplete);
		}
 
		private var _preLoadingText:TextField;
		/**
		 * createChildren
		 */
		private function createChildren():void
		{
			_preLoadingText = new TextField();
			_preLoadingText.text = "Loading...";
			_preLoadingText.textColor = 0x000000;
			_preLoadingText.x = (stage.stageWidth / 2) - (_preLoadingText.width / 2);
			_preLoadingText.y = (stage.stageHeight / 2) - (_preLoadingText.height / 2);
			_preLoadingText.autoSize = TextFieldAutoSize.CENTER;
			addChild(_preLoadingText);
		}
 
		/**
		 * Handle progress.
		 * @param event
		 */
		private function handleProgress(event:ProgressEvent):void
		{
			var percent:int = Math.floor(event.bytesLoaded / event.bytesTotal * 100);
			_preLoadingText.text = "Loading..." + percent + "%";
		}
 
		/**
		 * Handle load complete.
		 * @param event
		 */
		private function handleComplete(event:Event):void
		{
			this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, handleProgress);
			this.loaderInfo.removeEventListener(Event.COMPLETE, handleComplete);
		}
 
		/**
		 * Load main application.
		 * @param e
		 */
		private function loadApplication(event:Event):void
		{
			if (currentFrame == totalFrames)
			{
				removeEventListener(Event.ENTER_FRAME, loadApplication);
				stop();
 
				var cls:Class = getDefinitionByName("Application") as Class;
				addChild(new cls() as DisplayObject);
 
				removeChild(_preLoadingText);
				_preLoadingText = null;
			}
		}
	}
}



Application.as

package
{
	import flash.display.Sprite;
	import flash.events.Event;
 
	public class Application extends Sprite
	{
 
		private static var _instance:Application;
		/**
		 * Unique instance.
		 * @return
		 */
		public static function getInstance():Application
		{
			return _instance;
		}
 
		/**
		 * Application Constructor.
		 */
		public function Application()
		{
			super();
			addEventListener(Event.ADDED_TO_STAGE, initOnStage);
		}
 
		/**
		 * Handle ADDED_TO_STAGE event.
		 * @param event
		 */
		protected function initOnStage(event:Event):void
		{
			//remove ADDED_TO_STAGE listener.
			this.removeEventListener(Event.ADDED_TO_STAGE, initOnStage);
 
			//Set unique instance.
			if (!_instance)
				_instance = this;
 
			//...
		}
	}
}



通过Frame metadata tag


神奇的 Frame metadata tag - 用它做AS3 preloader

上一篇blog 的翻译了怎么用[Frame]做程序的模块化, 让我们再看那篇经典文章后, 大牛 keith 又是怎么用[Frame]实现了AS3的preloader: 原文章 Preloaders in AS3, 时间: Jan 21, 2007. 下面是概要性的翻译:

大家知道, flex程序是典型的2侦模型程序, preloader是在第一侦, 主程序在第二侦.

keith同学用[Frame]标签,主要是解决了让程序有2侦,并且让自定义的AS3 preloader类在第一侦.

直接在代码中分析吧,首先看主应用程序类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package {
     import flash.display.Sprite;
     import flash.display.Bitmap;
     
     //在主程序类中加入frame meta, MyPreloader 类就是一个简单的自定义的preloader类
     [Frame(factoryClass= "com.bit101.MyPreloader" )]
     public class Main extends Sprite
     {
         //为了体现preloader的价值, 故意选一个很大的图片文件,
         //这个主程序主要就是加载显示这个大图片
         [Embed(source= "big_asset.jpg" )]
         private var Asset:Class;
 
         public function Main()
         {
             init();
         }
 
         public function init(): void
         {
             var asset:Bitmap = new Asset();
             addChild(asset);
         }
     }
}

下面是 MyPreloader 代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.bit101
{
     import flash.display.DisplayObject;
     import flash.display.MovieClip;
     import flash.display.StageAlign;
     import flash.display.StageScaleMode;
     import flash.events.Event;
     import flash.utils.getDefinitionByName;
 
     //注意, 是继承自MovieClip而不是Sprite, 因为处理和侦相关
     public class MyPreloader extends MovieClip
     {
         public function MyPreloader()
         {
             stop();
             stage.scaleMode = StageScaleMode.NO_SCALE;
             stage.align = StageAlign.TOP_LEFT;
             addEventListener(Event.ENTER_FRAME, onEnterFrame);
         }
 
         public function onEnterFrame(event:Event): void
         {
             graphics.clear();
             if (framesLoaded == totalFrames)
             {
                 removeEventListener(Event.ENTER_FRAME, onEnterFrame);
                 nextFrame();
                 init();
             }
             else
             {
                 var percent: Number = root.loaderInfo.bytesLoaded / root.loaderInfo.bytesTotal;
                 graphics.beginFill( 0 );
                 graphics.drawRect( 0 , stage.stageHeight / 2 10 ,
                 stage.stageWidth * percent, 20 );
                 graphics.endFill();
             }
         }
 
         private function init(): void
         {
             //这里全部用的是反射机制, 没有直接用Main类,
             //这是避免直接import Main类, 这将引起Main以及它引用的类加入到了MyPreloader
             var mainClass:Class = Class(getDefinitionByName(“Main”));
             if (mainClass)
             {
                 //此处不能直接调用main的构造函数, 因为那样会涉及到stage, 而stage在被add as child之前还是空
                 var app: Object = new mainClass();
                 //主程序对象是作为 MyPreloader 的子对象, 而不是根的子对象
                 //这一点和flex preloader不一样
                 addChild(app as DisplayObject);
             }
         }
     }
}


两者区别

设前置载入帧为Preloader.as,被载入的主程序为Main.as

第一种通过编译选项

项目设置的可运行程序是Preloader。

Main不用设置可运行。

编译选项指定的是被加载的Main。

AS3 模块 优化不可优化模块。

外部一个swf通过Loader载入Preloader.swf后,可以通过loader.contentLoaderInfo.applicationDomain.getDefinition("Main")获得Main类。
可以获得Preloader类。


第二种通过Frame tag的

项目设置的可运行程序是Main。

Preloader不用设置为可运行程序。

Frame tag加在Main上。

AS3 模块 优化可以优化模块。因为模块指明的优化的可运行程序是 加载他 的主程序。

外部一个swf通过Loader载入Main.swf后,不可以通过loader.contentLoaderInfo.applicationDomain.getDefinition("Main")获得Main类。

可以获得Preloader类。估计只能通过Preloader内初始化Main类了。


我要啦免费统计
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Preloader分区是安卓系统中的一个分区,用于存储系统启动所需的预加载器文件。它位于底层存储设备的特定位置,负责引导系统的初始化过程。 Preloader分区的主要作用有以下几个方面: 1. 引导系统:Preloader分区中存储着引导加载程序,它是系统启动的重要组成部分。当我们打开安卓设备时,引导加载程序从Preloader分区中读取必要的文件和设置,然后开始加载操作系统。 2. 系统初始化:Preloader分区中还包含了系统的初始化程序和相关的配置文件。这些程序和文件用于初始化设备的硬件和软件环境,确保系统的正常运行。 3. 提供系统修复:如果设备发生了一些严重的故障,比如刷机失败或损坏系统文件,Preloader分区可以提供一种快速修复的方法。通过使用恢复模式或者刷入预加载器文件,可以修复设备的软件问题,恢复系统的正常运行。 需要注意的是,修改Preloader分区需要谨慎操作。错误的操作可能导致设备无法正常启动或者变得不稳定。因此,在修改Preloader分区之前,最好备份重要数据,并且确保所使用的预加载器文件是正确的,以防出现意外情况。 总结来说,Preloader分区是安卓设备中的一个重要分区,存储着引导加载程序和系统初始化所需的文件和设置。它在系统启动过程中发挥着重要的作用,并提供了一种修复设备的方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值