更新數據原理,訪問接口,將服務器數據抓取並下載到本地的臨時文件夾,當全部下載完成,卸載客戶端內容,出現升級界面,此時移動下載的內容到目標文件夾,移動完成再從新加載客戶端,訪問接口,下載文件,移動文件均是隊列完成。json
根據實際接口操做可替換源代碼中的必要代碼,如下是源碼:數組
DownloadControl.as服務器
package com.controls { import com.controls.download.ConnectionUtil; import com.controls.download.DownloadFile; import com.controls.download.FileManager; import com.models.Config; import com.models.events.AppEvent; import com.models.events.AppEventDispatcher; import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; import flash.net.URLVariables; import flash.utils.ByteArray; /** * @author Frost.Yen * @E-mail 871979853@qq.com * @create 2017-2-20 下午4:19:33 * */ public class DownloadControl { /** * 下載資源的計數器 */ private var _count:uint; /** * 第一級接口個數計數器 */ private var _firstCount:int; /** * 第二級接口個數計數器 */ private var _secondCount:int; /** * 第一級接口返回的數據,供第二級接口遞歸調用 */ private var _datas:Object; private static var _instance:DownloadControl; public function DownloadControl(s:S) { } public static function getInstance():DownloadControl { if(!_instance){ _instance = new DownloadControl(new S()); } return _instance; } public function reset():void { _count = 0; _firstCount = 0; _secondCount = 0; _datas = null; Config.downloadData = []; } /** * 一級接口請求 */ public function connection1():void { var connection:ConnectionUtil = new ConnectionUtil(); connection.connect(Config.connection+Config.config.link.item[_firstCount].@typeLink,Config.config.link.item[_firstCount].@name+".json","",null,onConnectComplete); } /** * 二級接口請求 */ private function connection2(datas:Object):void { var total:int = datas["data"]["response"].length; var variables:URLVariables = new URLVariables(); variables.parameter = datas["data"]["response"][_secondCount]["id"]; var connection:ConnectionUtil = new ConnectionUtil(); connection.connect(Config.connection+Config.config.link.item[_firstCount].@contentLink,Config.config.link.item[_firstCount]+"_"+_secondCount+".json","",variables,onConnectComplete1); function onConnectComplete1(data:Object):void { for(var i:int = 0;i<data["data"]["response"].length;i++){ if(data["data"]["response"][i]["videoUrl"]){ var label:String = "videoUrl"; } if(data["data"]["response"][i]["imgUrl"]){ label = "imgUrl"; } var len:int = data["data"]["response"][i][label].length; for(var j:int = 0;j<len;j++){//存儲下載的文件名稱 Config.downloadData.push(data["data"]["response"][i][label][j]["openFile"]); if(label == "videoUrl"){ Config.downloadData.push(data["data"]["response"][i][label][j]["vframe"]); } } } Config.jsonArr[_firstCount][_secondCount]["second"] = data["data"]["response"];//二級菜單保存 _secondCount++; trace("------>>"+_secondCount+"------"+total+"--\n"); if(_secondCount >= total){ _firstCount++; if(_firstCount>Config.config.link.item.length()-1){ //全部接口請求完成,將json保存到本地 var file:File = new File(Config.jsonPath+"data.json"); var fs:FileStream = new FileStream(); fs.open(file,FileMode.WRITE); fs.writeBytes(getByteArr(JSON.stringify(Config.jsonArr))); fs.close(); file = null; fs = null; //全部接口請求完成,開始下載 trace("------>>全部接口請求完成,開始下載---資源共:"+Config.downloadData.length+"個-----\n"); startDownload(); }else{ connection1(); } }else{ connection2(_datas); } } } private function onConnectComplete(data:Object):void { trace(JSON.stringify(data)); _datas = data; _secondCount=0; Config.jsonArr[_firstCount] = data["data"]["response"];//一級菜單保存 connection2(data); } /** * 開始下載 * @param isAll true表示全部資源同時下載 false表示資源隊列下載 */ private function startDownload(isAll:Boolean=true):void { if(isAll){ for(var i:int = 0;i<Config.downloadData.length;i++){ download(i); } }else{ download(_count); } function download(i:int):void { new DownloadFile().download(Config.source,Config.downloadData[i],Config.tempPath,Config.assets,onDownloaded); } function onDownloaded():void { trace("------>>第"+_count+"個資源下載完成\n"); _count++; if(_count == Config.downloadData.length){//Config.downloadData.length trace("------>>全部資源下載完成--------"); var tempList:Array = new File(Config.tempPath).getDirectoryListing(); AppEventDispatcher.getInstance().dispatchEvent(new AppEvent(AppEvent.DOWNLOAD_COMPLETE,tempList.length)); }else{ if(!isAll){ download(_count); } } } } public function startMove():void { FileManager.deleteFilesByNotSame(Config.downloadData,Config.assets); FileManager.startMoveFiles(File.applicationDirectory.nativePath+"/source/",Config.assets,onMoveComplete); } private function onMoveComplete():void { trace("------>>全部資源移動完成--------\n"); AppEventDispatcher.getInstance().dispatchEvent(new AppEvent(AppEvent.UPDATE_COMPLETE)); } /** * 將String轉換成ByteArray類型 * @param param 被轉換的String * @return ByteArray 轉換後的ByteArray * */ private function getByteArr(param:String):ByteArray { var bytes:ByteArray = new ByteArray; bytes.writeUTFBytes(param); return bytes; } } } class S{ }
接口鏈接工具類 ConnectionUtil.asapp
package com.controls.download { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.URLVariables; import flash.utils.ByteArray; /** * 鏈接接口工具類 * @author Frost.Yen * @E-mail 871979853@qq.com * @create 2017-2-16 下午2:50:58 * */ public class ConnectionUtil extends EventDispatcher { private var _ldr:URLLoader; /** * 將返回數據寫入到本地,此爲本地存儲路徑 */ private var _localPath:String; /** * 將返回數據寫入到本地,此爲文件名稱 */ private var _fileName:String; /** * 接口鏈接地址 */ private var _connectionURL:String; /** * 接口所需參數 */ private var _argument:String; /** * 從接口獲取的數據 */ public var data:Object; /** * 接口鏈接成功,獲取數據後回調函數 */ public var onConnectSucceed:Function=null; public function ConnectionUtil() { _ldr = new URLLoader(); _ldr.addEventListener(Event.COMPLETE,onConnectComplete); _ldr.addEventListener(IOErrorEvent.IO_ERROR,onError); } /** * 鏈接接口成功 */ private function onConnectComplete(e:Event):void { var str:String = e.target.data; data = JSON.parse(str); trace("\n<<----------------- aticon: "+_connectionURL+" ----------------- argument: "+_argument+" -------------------------->>\nresult: \n"+str); if(data.code == "200"){ //將json寫入本地 /*var file:File = new File(_localPath+_fileName); var fs:FileStream = new FileStream(); fs.open(file,FileMode.WRITE); fs.writeBytes(getByteArr(str)); fs.close(); file = null; fs = null;*/ if(onConnectSucceed!=null) onConnectSucceed(data); } } private function onError(e:IOErrorEvent):void { trace("error:"+e.text); } /** * 訪問接口,獲取數據 * @param connectPath:接口地址 * @param path : 將接口返回的json寫入本地,此爲本地地址 */ public function connect(connectPath:String,fileName:String,localPath:String="",argument:URLVariables=null,callback:Function=null,who:String=""):void { _connectionURL = connectPath; _fileName = fileName; localPath ==""?_localPath = File.applicationDirectory.nativePath+"/json/": _localPath = localPath; trace("接口地址:"+connectPath); var request:URLRequest = new URLRequest(connectPath); request.method = URLRequestMethod.POST; if(argument){ request.data = argument; _argument = argument.parameter; }else{ _argument = "無參數"; } _ldr.load(request); if(callback!=null) onConnectSucceed = callback; } /** * 將String轉換成ByteArray類型 * @param param 被轉換的String * @return ByteArray 轉換後的ByteArray * */ private function getByteArr(param:String):ByteArray { var bytes:ByteArray = new ByteArray; bytes.writeUTFBytes(param); return bytes; } } }
下載文件類 DownloadFile.as ide
package com.controls.download { import com.models.Config; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestHeader; import flash.utils.ByteArray; /** * 下載文件工具類 * @author Frost.Yen * @E-mail 871979853@qq.com * @create 2017-2-16 下午12:55:22 * */ public class DownloadFile extends EventDispatcher { private var _downloadLoader:URLLoader; /** * 是否下載完成標識 */ private var _downloadEnd:Boolean; private var _startPoint:uint = 0; private var _endPoint:uint = 0; private var _total:uint = 0; /** * 文件名(xx.jpg,xx.flv) */ private var _fileName:String; /** * 下載時保存的臨時路徑,下載完成後須要從這個地址移動到程序訪問的路徑 */ private var _tempPath:String = ""; /** * 程序訪問資源的本地路徑 */ private var _localPath:String = ""; /** * 服務端抓取數據的路徑 */ private var _remotePath:String = ""; /** * 下載完成回調函數 */ private var _downloadComplete:Function; public function DownloadFile() { init(); } private function init():void { _downloadLoader = new URLLoader(); _downloadLoader.dataFormat = URLLoaderDataFormat.BINARY; _downloadLoader.addEventListener(Event.COMPLETE,onLoaded); _downloadLoader.addEventListener(IOErrorEvent.IO_ERROR,onError); } private function onLoaded(e:Event):void { if(e.target.data.length == 0){ writeBytes(_tempPath,e.target.data,0,e.target.data.length); this.dispatchEvent(new Event(Event.COMPLETE)); if(_downloadComplete!=null) _downloadComplete(); }else{ if(_downloadEnd){ _startPoint = _endPoint; writeBytes(_tempPath,e.target.data,0,e.target.data.length); this.dispatchEvent(new Event(Event.COMPLETE)); if(_downloadComplete!=null) _downloadComplete(); }else{ _startPoint = _endPoint; writeBytes(_tempPath,e.target.data,0,e.target.data.length-1); stepDownload(); } } } /** * 將數據寫入到本地,即下載 * @param path 本地保存地址 * @param bytes 要寫入的字節數組。 * @param offset 從零開始的索引,指定在數組中開始寫入的位置。 * @paramlength 一個無符號整數,指定在緩衝區中的寫入範圍。 */ private function writeBytes(path:String,bytes:ByteArray, offset:uint=0, length:uint=0):void { var file:File = new File(path+_fileName); var fs:FileStream = new FileStream();; fs.open(file,FileMode.UPDATE); fs.position = fs.bytesAvailable;//將指針指向文件尾 fs.writeBytes(bytes,offset,length);//在文件中寫入新下載的數據 fs.close(); } /** * 分步下載 */ private function stepDownload():void { _endPoint += 10000000; if(_endPoint > _total ){ _endPoint = _total; _downloadEnd = true; } var request:URLRequest = new URLRequest(_remotePath+_fileName); var header:URLRequestHeader = new URLRequestHeader("Range","bytes="+_startPoint+"-"+_endPoint); request.requestHeaders.push(header); _downloadLoader.load(request); } /** * 開始下載文件 * @param remoteURL 數據存放的遠程地址 * @param fileName 下載的文件名 * @param tempPath 下載保存到本地的臨時目錄 * @param localPath 最終程序訪問的本地目錄 */ public function download(remotePath:String,fileName:String,tempPath:String,localPath:String,callback:Function=null):void { _remotePath = remotePath; _fileName = fileName; _tempPath = tempPath; _localPath = localPath; _downloadComplete = callback; _downloadEnd = false; _startPoint = 0; _endPoint = 0; var file:File = new File(_localPath+_fileName); if(file.exists){//假如存在此文件,就不下載,跳過 this.dispatchEvent(new Event(Event.COMPLETE));//能夠回調,能夠派發 if(_downloadComplete!=null) _downloadComplete(); }else{ _downloadLoader.addEventListener(ProgressEvent.PROGRESS,onProgress); _downloadLoader.addEventListener(IOErrorEvent.IO_ERROR,onError); try { _downloadLoader.load(new URLRequest(_remotePath+_fileName)); } catch(error:Error) { trace(error.message); } } } private function onProgress(e:ProgressEvent):void { _total = _downloadLoader.bytesTotal; _downloadLoader.removeEventListener(ProgressEvent.PROGRESS,onProgress); _downloadLoader.close(); stepDownload(); } private function onError(e:IOErrorEvent):void { trace(e.text); //錯誤時跳過,繼續下一個下載 if(_downloadComplete!=null) _downloadComplete(); } /** * 釋放下載工具 */ public function dispose():void { _downloadLoader.removeEventListener(Event.COMPLETE,onLoaded); _downloadLoader.removeEventListener(IOErrorEvent.IO_ERROR,onError); _downloadLoader.removeEventListener(ProgressEvent.PROGRESS,onProgress); _downloadLoader.close(); _downloadLoader = null; } } }
文件操做類 FileManager.as 函數
package com.controls.download { import flash.events.Event; import flash.filesystem.File; /** * 文件操做類 * @author Frost.Yen * @E-mail 871979853@qq.com * @create 2017-2-20 上午11:34:16 * */ public class FileManager { private static var _moveCount:int; private static var _moveComplete:Function; private static var _targetDir:String; private static var _tempDir:String; private static var _templist:Array; public function FileManager() { } public static function reset():void { _moveCount = 0; _templist = null; } /** * 在目標目錄下刪除數組中不存在的文件 * @param filesName 文件名數組 * @param targetDir 目標文件夾 */ public static function deleteFilesByNotSame(filesName:Array,targetDir:String):void { var targetList:Array = new File(targetDir).getDirectoryListing(); for(var i:int;i<targetList.length;i++){ if(filesName.indexOf(targetList[i].name)==-1){ (targetList[i] as File).deleteFile(); trace("刪除文件:"+(targetList[i] as File).nativePath+"\n"); } } } /** * 開始移動文件 * @param tempDir 存儲下載文件的臨時目錄 * @param targetDir 須要移動到的目標目錄 * @callba 移動完成,回調函數 */ public static function startMoveFiles(tempDir:String,targetDir:String,callback:Function):void { _moveCount = 0; _targetDir = targetDir; _tempDir = tempDir; _moveComplete = callback; _templist = new File(_tempDir).getDirectoryListing(); if(_templist.length){ moveFiles(); }else{ _moveComplete(); } } /** * 移動文件 */ private static function moveFiles():void { var fromFile:File = new File(_tempDir+_templist[_moveCount].name); var toFile:File = new File(_targetDir+_templist[_moveCount].name); trace("移動文件:"+_moveCount+"個-->>"+_templist[_moveCount].name); trace(_tempDir+_templist[_moveCount].name,_targetDir+_templist[_moveCount].name); fromFile.moveToAsync(toFile,true); fromFile.addEventListener(Event.COMPLETE,onFileMoveComplete); } private static function onFileMoveComplete(e:Event):void { _moveCount++; if(_moveCount>_templist.length-1){ //所有移動完成 _moveComplete(); }else{ moveFiles(); } } } }
還有個數據存儲類 Config.as工具
package com.models { import flash.filesystem.File; /** * * @author Frost.Yen * @E-mail 871979853@qq.com * @create 2017-2-16 下午1:35:43 * */ public class Config { public static var config:XML; /** * 服務器鏈接地址 */ public static var connection:String; /** * 遠程資源地址 cdn */ public static var source:String; /** * 本地資源地址 */ public static var assets:String; /** * 存儲全部下載資源的信息(目前僅存文件名稱) */ public static var downloadData:Array = []; /** * 寫入到本地的json目錄地址 */ public static var jsonPath:String = File.applicationDirectory.nativePath+"/data/"; /** * 下載資源的臨時存放目錄 */ public static var tempPath:String = File.applicationDirectory.nativePath+"/source/"; /** * 接口返回的json數據組合 */ public static var jsonArr:Array = []; public function Config() { } } }
若要爲己所用,據具體需求請改代碼。ui