http://blog.csdn.net/damenhanter/article/details/50273303

上一篇我们分析了   接下来我们继续分析 LoadManager类。

当我们的任务下载完成后,我们需要对任务的委托进行回调到调用对象。

我们初步加入的委托有 complete、process、error ,接下来分别对这三个委托写相应的回调。

[csharp] 

  1. /// <summary>  

  2. ///  下载错误回调  

  3. /// </summary>  

  4. public void ErrorDelegateHandle(LoadRequest request) {  

  5.     if (request.errorFunction != null) {  

  6.         int count = request.errorFunction.GetInvocationList().GetLength(0);  

  7.         for (int i = 0; i < count; i++) {  

  8.             LoadRequest.ErrorDelegate errorFunc = (LoadRequest.ErrorDelegate)request.errorFunction.GetInvocationList()[i];  

  9.             try {  

  10.                 errorFunc.Invoke(request);  

  11.             } catch (Exception e) {  

  12.                 Debug.LogWarning("exception:" + e.Message);  

  13.             }  

  14.         }  

  15.     }  

  16. }  

  17.   

  18. /// <summary>  

  19. ///  下载进度回调  

  20. /// </summary>  

  21. public void ProcessDelegateHandle(LoadRequest request) {  

  22.     if (request.processFunction != null) {  

  23.         int count = request.processFunction.GetInvocationList().GetLength(0);  

  24.         for (int i = 0; i < count; i++) {  

  25.             LoadRequest.ProcessDelegate processFunc = (LoadRequest.ProcessDelegate)request.processFunction.GetInvocationList()[i];  

  26.             try {  

  27.                 processFunc.Invoke(request.wwwObject.progress, request.wwwObject.bytesDownloaded);  

  28.             } catch (Exception e) {  

  29.                 Debug.LogWarning("exception:" + e.Message);  

  30.             }  

  31.         }  

  32.     }  

  33. }  

  34.   

  35. /// <summary>  

  36. ///  任务下载完成回调  

  37. /// </summary>  

  38. /// <param name="request"></param>  

  39. /// <param name="param"></param>  

  40. public void CompleteDelegateHandle(LoadRequest request, LoadParam param) {  

  41.     if (request.completeFunction != null) {  

  42.         int count = request.completeFunction.GetInvocationList().GetLength(0);  

  43.         for (int i = 0; i < count; i++) {  

  44.             if (i < request.customParams.Count) {  

  45.                 param.param = request.customParams[i];  

  46.             }  

  47.             LoadRequest.DownCompleteDelegate completeFunc = (LoadRequest.DownCompleteDelegate)request.completeFunction.GetInvocationList()[i];  

  48.             try {  

  49.                 completeFunc.Invoke(param);  

  50.             } catch (Exception exception) {  

  51.                 Debug.LogWarning("exception:" + exception.Message);  

  52.             }  

  53.         }  

  54.     }  

  55. }  



1. 在上面我们注意到有一个陌生的类 LoadParam. 这个类是用来做什么的呢?

很简单,因为我们下载完成后会进行存储所有的下载结果,方便后续下载相同资源时可以马上调用。所以我们需要专门的对象来存放。

我们把所有类型写到一个类里面,然后标注好该对象的对应URL、filetype。

如下:

[csharp] 

  1. /** 

  2.  * 任务下载的资源 

  3.  * create by chensh 2014.10.27 10:35 

  4.  */  

  5.   

  6. using UnityEngine;  

  7. using System.Collections;  

  8.   

  9.   

  10. namespace AssemblyCSharp {  

  11.     public class LoadParam {  

  12.         // 加载的文件类型  

  13.         public string fileType;  

  14.         // 加载的路径  

  15.         public string url;  

  16.   

  17.         // 自定义参数  

  18.         public object param = null;  

  19.         // 图片  

  20.         public Texture2D texture2D;  

  21.         // 文本  

  22.         public string text = "";  

  23.         // unity3d格式文件,目前针对场景打包的unity3d格式文件  

  24.         public AssetBundle assetBundle = null;  

  25.         // json文件  

  26.         public string jsonData;  

  27.         // 二进制文件  

  28.         public byte[] byteArr;  

  29.         // 音频文件  

  30.         public AudioClip audioClip;  

  31.         // 模块资源打包格式文件  

  32.         public UIAtlas uiAtlas;  

  33.         // fbx打包的文件对象  

  34.         public UnityEngine.Object mainAsset;  

  35.         // font文件  

  36.         public UIFont font;  

  37.          

  38.     }  

  39. }  



2. 此时我们需要一个函数。来解析下载完后的资源,并保存到 LoadParam 中。

[csharp] 

  1. /// <summary>  

  2.     ///  解析下载内容  

  3.     /// </summary>  

  4.     public LoadParam ParseLoadParamFromLoadRequest(LoadRequest request) {  

  5.         LoadParam param = new LoadParam();  

  6.         param.url = request.requestURL;  

  7.         param.priority = request.priotiry; // 为何param需要记录优先级?  

  8.         param.fileType = request.fileType;  

  9.   

  10.         switch (request.fileType) {  

  11.             case LoadFileType.IMAGE:  

  12.                 try {  

  13.                     param.texture2D = request.wwwObject.texture;  

  14.                     param.texture2D.Compress(false);    // compress 有何影响  

  15.                 } catch (Exception exception) {  

  16.                     Debug.LogWarning("read texture2d error:" + request.requestURL +"\n" + exception.Message);  

  17.                 }  

  18.                 break;  

  19.             case LoadFileType.TXT:  

  20.                 try {  

  21.                     param.text = request.wwwObject.text;  

  22.                 } catch (Exception exception) {  

  23.                     Debug.LogWarning("read text error:" + request.requestURL + "\n" + exception.Message);  

  24.                 }  

  25.                 break;  

  26.             case LoadFileType.UNITY3D:  

  27.                 try {  

  28.                     if (request.wwwObject.assetBundle != null) {  

  29.                         param.assetBundle = request.wwwObject.assetBundle;  

  30.                     }  

  31.                 } catch (Exception exception) {  

  32.                     Debug.LogWarning("read assetBundle error:" + request.requestURL + "\n" + exception.Message);  

  33.                 }  

  34.                 break;  

  35.             case LoadFileType.MODULE_RESOURCE:  

  36.                 try {  

  37.                     UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();  

  38.                     int length = data.Length;  

  39.                     for (int i = 0; i < length; i++) {  

  40.                         if (data[i] is GameObject) {  

  41.                             param.uiAtlas = (data[i] as GameObject).GetComponent<UIAtlas>();  

  42.                             break;  

  43.                         }  

  44.                     }  

  45.                     request.wwwObject.assetBundle.Unload(false);  

  46.                 } catch (Exception exception) {  

  47.                     Debug.LogWarning("read uiatlas error:" + request.requestURL + "\n" + exception.Message);  

  48.                 }  

  49.                 break;  

  50.             case LoadFileType.JSON:  

  51.                 try {  

  52.                     param.jsonData = request.wwwObject.text.Trim();  

  53.                 } catch (Exception exception) {  

  54.                     Debug.LogWarning("read  json error:" + request.requestURL + "\n" + exception.Message);  

  55.                 }  

  56.                 break;  

  57.             case LoadFileType.FBX:  

  58.                 try {  

  59.                     param.mainAsset = request.wwwObject.assetBundle.mainAsset;  

  60.                 } catch (Exception exception) {  

  61.                     Debug.LogWarning("read  fbx error:" + request.requestURL + "\n" + exception.Message);  

  62.                 }  

  63.                 break;  

  64.             case LoadFileType.BINARY:  

  65.             case LoadFileType.BINARY_BG:  

  66.                 try {  

  67.                     param.byteArr = request.wwwObject.bytes;  

  68.                 } catch (Exception exception) {  

  69.                     Debug.LogWarning("read  binary error:" + request.requestURL + "\n" + exception.Message);  

  70.                 }  

  71.                 break;  

  72.             case LoadFileType.AUDIO:  

  73.                 try {  

  74.                     UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();  

  75.                     int length = data.Length;  

  76.                     for (int i = 0; i < length; i++) {  

  77.                         if (data[i] is AudioClip) {  

  78.                             param.audioClip = data[i] as AudioClip;  

  79.                             break;  

  80.                         }  

  81.                     }  

  82.                     request.wwwObject.assetBundle.Unload(false);  

  83.                 } catch (Exception exception) {  

  84.                     Debug.LogWarning("read audio error:" + request.requestURL + "\n" + exception.Message);  

  85.                 }  

  86.                 break;  

  87.             case LoadFileType.FONT:  

  88.                 try {  

  89.                     UnityEngine.Object[] data = request.wwwObject.assetBundle.LoadAll();  

  90.                     int length = data.Length;  

  91.                     for (int i = 0; i < length; i++) {  

  92.                         if (data[i] is UnityEngine.Transform) {  

  93.                             param.font = (data[i] as UnityEngine.Transform).GetComponent<UIFont>();  

  94.                             break;  

  95.                         }  

  96.                     }  

  97.                     request.wwwObject.assetBundle.Unload(false);  

  98.                 } catch (Exception exception) {  

  99.                     Debug.LogWarning("read  font error:" + request.requestURL + "\n" + exception.Message);  

  100.                 }  

  101.                 break;  

  102.         }  

  103.         return param;  

  104.     }  


3.我们发现,似乎还没有对下载队列进行检测,即检测WWW类下载的状态。是已经下载完成了呢,还是下载出错。

这个时候我们需要一个定时器。

每隔一定时间对下载队列进行检测,我们在构造函数那里添加一个定时器。

[csharp] 

  1. public LoadManager() {  

  2.        Application.backgroundLoadingPriority = ThreadPriority.Low;  

  3.        // add timer to check download queue  

  4.        FrameTimerManager.getInstance().add(1, 0, CheckQueue);  

  5.    }  


其中的 CheckQueue() 函数是检测函数。

[csharp] 

  1. /// <summary>  

  2.     ///  定时器下,在每帧对下载队列进行检测  

  3.     ///  如果下载有问题,或者超时,则清除  

  4.     ///  如果下载完成,则解析下载结果,并进入completeDict中  

  5.     /// </summary>  

  6.     public void CheckQueue() {  

  7.         if (!isLoading) return;  

  8.         foreach (KeyValuePair<string, LoadRequest> pair in loadDict) {  

  9.             LoadRequest request = pair.Value;  

  10.             request.loadTotalFrames++;  

  11.             // deal error  

  12.             if ((request.wwwObject != null && request.wwwObject.error != null) || request.isTimeOut) {  

  13.                 if (request.requestURL.Contains(".apk") || request.requestURL.Contains(".ipa")) {  

  14.                     return;  

  15.                 }  

  16.                 request.alreadyDeal = true;  

  17.                 loadDict.Remove(request.requestURL);  

  18.                 ErrorDelegateHandle(request);  

  19.                 if (request.isTimeOut) {  

  20.                     Debug.LogWarning("Load time out:" + request.requestURL);  

  21.                 } else {  

  22.                     Debug.LogWarning("Load error:" + request.requestURL);  

  23.                 }  

  24.                 MoveRequestFromWaitDictToLoadDict();  

  25.                 break;  

  26.             }  

  27.   

  28.             //   

  29.             if (!request.alreadyDeal) {  

  30.                 ProcessDelegateHandle(request);  

  31.                 // if done  

  32.                 if (request.wwwObject != null && request.wwwObject.isDone) {  

  33.                     LoadParam param = ParseLoadParamFromLoadRequest(request);  

  34.                     if (request.fileType != LoadFileType.BINARY) {  

  35.                         completeDict.Add(request.requestURL, param);  

  36.                     }  

  37.                     //  

  38.                     CompleteDelegateHandle(request, param);  

  39.                     //  

  40.                     request.alreadyDeal = true;  

  41.                     loadDict.Remove(request.requestURL);  

  42.                     MoveRequestFromWaitDictToLoadDict();  

  43.                     break;  

  44.                 }  

  45.             }  

  46.   

  47.         }  

  48.     }  



至此,我们的LoadManager类即完成相应的功能。