air'软件更新

首先介绍下自己的思路:现在air都分模块化的,所以也是分模块进行更新,外加程序进行更新,

就是从远程download下载swf然后替换本地的,程序更新是先down下来,然后使用自带的updater进行更新

说实在的我的flex有时候也弄不懂,有时候改了一个地方,不知道编译器会更改哪里,更新要先测试,是不是指更改了这一个模块;

好了上代码,首先是模块更新

 

package com.fileOperations
{
	

	public class FileModuleUpdate extends Sprite
	{
		public function FileModuleUpdate()
		{
		}
		/**
		 * 需要更新的数量
		 * */
		private var swfCount:Number = 0;
		/**
		 * 已经更新的数量
		 * */
		private var updatedCount:Number = 0;
		
		private var newVersionXML:XML;
		/**
		 * 获取新的配置文件
		 * */
		public function getNewFileVersionConfigXMl(url:String):void{
			swfCount = 0;
			updatedCount = 0;
			var loadUrl:URLLoader = new URLLoader();
			loadUrl.load(new URLRequest(url));
			loadUrl.addEventListener(Event.COMPLETE,checkIsUpdated);
		}
		
		private var url:String;//地址
		private var _description:String;//升级描述
		/**
		 * 检查这个文件是不是需要更新,由总的文件版本号确定
		 * */
		private function checkIsUpdated(event:Event):void{
			var loader:URLLoader = URLLoader(event.target);
			var xml:XML = XML(loader.data);
			newVersionXML = xml;
			var object:XML;
			for(var i:int = 0;i<xml.children().length();i++){
				object = xml.children()[i] as XML;
				var id:String  = object.attribute("id");
				if(id == "v_main"){ 
					var version:String = (object.children()[0] as XML).@['value'];
					var dic :Dictionary = IocAppFacade.getInstance().getObject("v_main") as Dictionary;
					if(getIsHideVersion(dic,version)){
						url = (object.children()[1] as XML).@['value'];
						description = (object.children()[2] as XML).@['value'];
						dispatchEvent(new FileUpdateEvent(FileUpdateEvent.FILE_HAVE_UPDATE,xml));
					}else{
						dispatchEvent(new FileUpdateEvent(FileUpdateEvent.NOT_FILE_HAVE_UPDATE));
					}
					break;
				}
			}
			loader.close();
		}
		
		public function updateFileMoudle(xml:XML):void{
			updateThisSystem(xml);
		}
		
		/**
		 * 判断版本号的大小
		 * */
		private function getIsHideVersion(dic:Dictionary,version:String):Boolean{
			if(dic==null||version.length==0){return false;}
			var local:Number = Number((dic['version'] as String).replace(".",""));
			var online:Number = Number(version.replace(".",""));
			return online>local;
		}
		/**
		 * 检查这个文件是不是需要更新
		 * */
		private function updateThisSystem(xml:XML):void{
			var object:XML;
			var id:String;
			var version:String;
			var palce:String;
			for(var i:int = 2;i<xml.children().length();i++){
				object = xml.children()[i] as XML;
				id = object.attribute("id");
				version= (object.children()[0] as XML).@['value'];
				palce= (object.children()[1] as XML).@['value'];
				var dic :Dictionary = IocAppFacade.getInstance().getObject(id) as Dictionary;
				if(dic==null||getIsHideVersion(dic,version)){
					swfCount++;
					if(palce.lastIndexOf("swf")!=-1){
						updateThisModule(palce);
					}else{
						updateThisConfig(palce);
					}
				}
			}
		}
		
		private function updateThisConfig(path:String):void{
			var loadUrl:URLLoader = new URLLoader();
			loadUrl.load(new URLRequest(url+path));
			loadUrl.addEventListener(Event.COMPLETE,function():void{
				var xml:XML = XML(loadUrl.data);
				saveXML(xml,path);
				swfUpdateSuccess(null);
				loadUrl.close();
			});
				
		}
		/**
		 * 更新这个,模块
		 * */
		private function updateThisModule(path:String):void{
			var loadUrl:URLLoader = new URLLoader();
			loadUrl.dataFormat = URLLoaderDataFormat.BINARY;
			loadUrl.load(new URLRequest(url+path));
			loadUrl.addEventListener(Event.COMPLETE,function():void{
				var stream:FileStream = new FileStream();
				var fileName:String = getFileName(path);
				var file:File = new File(fileName);
				stream.openAsync(file, FileMode.UPDATE);
				stream.addEventListener(IOErrorEvent.IO_ERROR,function(e:IOErrorEvent):void{
					swfUpdateSuccess(null);
					stream.close();	//这个是用来放置用户磁盘保护这样就会报错,所以会监视,关闭
				});
				stream.addEventListener(Event.CLOSE,swfUpdateSuccess);
				stream.writeBytes(loadUrl.data);
				stream.close();
				loadUrl.close();
			});
			loadUrl.addEventListener(IOErrorEvent.IO_ERROR,function(e:IOErrorEvent):void{
				swfUpdateSuccess(null);
				trace(e.toString()+"--------------流错误");
				loadUrl.close();
			});
		}
		
		
		private function swfUpdateSuccess(e:Event):void{
			updatedCount++;
			var percentage:Number = Math.floor(updatedCount*100/swfCount);
			dispatchEvent(new FileUpdateEvent(FileUpdateEvent.UPDATE_PERCENTAGE,percentage));
			if(updatedCount == swfCount){
				dispatchEvent(new FileUpdateEvent(FileUpdateEvent.UPDATE_COMPLETE));
				saveXML(newVersionXML,"更新文件XML名");
			}
			
		}
		/**
		 * 对xml文件进行存储
		 * */
		private function saveXML(xml:XML,name:String):void{
			var xmlOperation:ConfigXmlOperation = new ConfigXmlOperation();
			xmlOperation.fileName = File.applicationDirectory.resolvePath(name).nativePath;
			xmlOperation.writeConfigXml(xml);
		}
		
		/**
		 * 获取文件的真是路径
		 * */
		private function getFileName(path:String):String{
			var fileName:String = File.applicationDirectory.resolvePath("根目录的一个文件名").nativePath;
			fileName = fileName.substring(0,fileName.indexOf("根目录的一个文件名"));
			return fileName += path;
		}
		
		public function get description():String{
			return _description;
		}
		public function set description(value:String):void{
			_description = value;
		}
		
	}
}

 然后是air文件更新代码:

package com.copote.fileOperations
{


	public class AirFileUpdate extends Sprite
	{
		public function AirFileUpdate()
		{
		}
		/**
		 * 文件的地址
		 * */
		private var url:String;
		/**
		 * 文件的版本号
		 * */
		private var newVersion:String;
		
		
		public function checkMainAirIsNeedUpdate(xml:XML):void{
			var object:XML;
			for(var i:int = 0;i<xml.children().length();i++){
				object = xml.children()[i] as XML;
				var id:String  = object.attribute("id");
				if(id == "文件名"){ 
					newVersion = (object.children()[0] as XML).@['value'];
					var dic:Dictionary = IocAppFacade.getInstance().getObject("文件名") as Dictionary;
					url = dic['palce'];
					dispatchEvent(new FileUpdateEvent(FileUpdateEvent.AIR_HAVE_UPDATE,getIsHideVersion(dic,newVersion)));
					break;
				}
			}
		}
		
		/**
		 * 判断版本号的大小
		 * */
		private function getIsHideVersion(dic:Dictionary,version:String):Boolean{
			var local:Number = Number((dic['version'] as String).replace(".",""));
			var online:Number = Number(version.replace(".",""));
			return online>local;
		}
		
		
		public function updateAIR():void{
			var file:File = new File(fileName);
			var loadUrl:URLLoader = new URLLoader();
			loadUrl.dataFormat = URLLoaderDataFormat.BINARY;
			loadUrl.load(new URLRequest(url));
			loadUrl.addEventListener(ProgressEvent.PROGRESS,getLoadProgress);
			loadUrl.addEventListener(Event.COMPLETE,function():void{
				var stream:FileStream = new FileStream();
				var file:File = new File(fileName);
				stream.openAsync(file, FileMode.UPDATE);
				stream.addEventListener(IOErrorEvent.IO_ERROR,function(e:IOErrorEvent):void{
					stream.close();	//这个是用来放置用户磁盘保护这样就会报错,所以会监视,关闭
				});
				stream.addEventListener(Event.CLOSE,updateFile);
				stream.writeBytes(loadUrl.data);
				stream.close();
			});
			loadUrl.addEventListener(IOErrorEvent.IO_ERROR,function(e:IOErrorEvent):void{
				trace(e.toString()+"--------------流错误");
				loadUrl.close();
			});
		}
		
		private function get fileName():String{
			var fileName:String = File.applicationDirectory.resolvePath("根目录的一个文件名").nativePath;
			fileName = fileName.substring(0,fileName.indexOf("根目录的一个文件名"));
			return fileName+"文件名";
		}
		
		private function updateFile(event:Event):void{
			var updater:Updater=new Updater ; 
			var airFile:File= File.applicationDirectory.resolvePath("文件名"); 
			updater.update(airFile,newVersion);
		}
		
		private function getLoadProgress(e:ProgressEvent):void{
			var percentage:Number = Math.floor(e.bytesLoaded*100/e.bytesTotal);
			dispatchEvent(new FileUpdateEvent(FileUpdateEvent.UPDATE_PERCENTAGE,percentage));
		}
	}
}

 更新中的事件

package com.copote.fileOperations.event
{
	import flash.events.Event;

	public class FileUpdateEvent extends Event
	{
		/**
		 * 文件升级
		 * */
		public static const  FILE_HAVE_UPDATE:String = "fileHaveUpdate";
		/**
		 * 文件升级
		 * */
		public static const NOT_FILE_HAVE_UPDATE:String = "notFileHaveUpdate";
		/**
		 * 主程序升级
		 * */
		public static const AIR_HAVE_UPDATE:String = "airFileHaveUpdate";
		/**
		 * 以加载的百分比
		 * */
		public static const UPDATE_PERCENTAGE:String = "updatePercentage";
		/**
		 * 更新完成
		 * */
		public static const UPDATE_COMPLETE:String = "updateComplete";
		
		public var data:Object;
		
		public function FileUpdateEvent(type:String, mydata:Object =null, bubbles:Boolean = false, cancelable:Boolean = false)
		{
			super(type, bubbles,cancelable);
			data = mydata;
		}
	}
}

 界面就不写了,这里自己接触了流和文件读写,学习了下,配置文件时读取的xml

像这样子:

<object id="v_main" class="flash.utils.Dictionary">
		<property name="version" value="0.3.6"></property>
		<property name="palce" value="连接文件的目录"></property>
		<property name="description" value="增加了一部分功能,修改了部分bug,对一些界面做了美化"></property>
	</object>

本地配置文件使用spring来读取的 

存在的问题是,如果要更新就要对每一个模块写配置,比较麻烦

 

你可能感兴趣的:(AIR)