Unity3d热更新之下载
著热更新框架:uluaFramework_UIGUI-master,在Unity热更新时,先释放资源(StreamingAssets --> DataPath),再从服务端下载资源(或者其它下载网络文件的时候)
(1)下载方案
启动一个线程,每隔几毫秒询问队列,队列中下载Action数大于0,则开启WebClient异步下载
(2)问题
(1)用windows自带的iis搭建的web服务,在下载资源时始终下载不下来,但又没有异常提示。luaFramework使用WebClient.DownloadFileAsync时,若下载发生异常,并没有做异常处理
解决办法:
WebClient异步下载时,tryCatch捕捉不到异常,需要在WebClient.DownloadFileComplete回调中捕捉
(2)本地目录错误时,依然捕捉不到异常
(3).net的一些封装库有时并不可靠,正式项目时需要改用其它下载方案或用TCP自己实现
1 /// <summary> 2 /// 下载任务 3 /// </summary> 4 public class DownloadAction 5 { 6 /// <summary> 7 /// 下载Action编号 8 /// </summary> 9 public string id; 10 /// <summary> 11 /// 下载远程url、本地url 12 /// </summary> 13 public List<string> actionParams = new List<string>(); 14 15 public DownloadAction(string id, string fileName, string localPath, string remoteUrl) 16 { 17 this.id = id; 18 List<string> actionParams = new List<string>(); 19 actionParams.Add(fileName); 20 actionParams.Add(localPath); 21 actionParams.Add(remoteUrl); 22 this.actionParams = actionParams; 23 } 24 } 25 26 public class DownloadManager : MonoBehaviour 27 { 28 public Thread queryThread; 29 public Queue<DownloadAction> actionQueue = new Queue<DownloadAction>(); 30 31 /// <summary> 32 /// WebClient集合,用于释放内存 33 /// </summary> 34 private List<WebClient> clientList = new List<WebClient>(); 35 36 /// <summary> 37 /// 计时器 38 /// </summary> 39 Stopwatch sw = new Stopwatch(); 40 41 static readonly object lockObject = new object(); 42 43 void Start() 44 { 45 queryThread = new Thread(OnUpdate); 46 queryThread.Start(); 47 48 //添加两个下载任务 49 string locaPath1 = "e:/StreamingAssets/a.jpg"; 50 string remoteUrl1 = "http://localhost:8080/manager/StreamingAssets/a.jpg"; 51 DownloadAction action1 = new DownloadAction("111", "a.jpg", locaPath1, remoteUrl1); 52 actionQueue.Enqueue(action1); 53 54 string locaPath2 = "e:/StreamingAssets/zhangwuji.mp4"; 55 string remoteUrl2 = "http://localhost:8080/manager/StreamingAssets/zhangwuji.mp4"; 56 DownloadAction action2 = new DownloadAction("222", "zhangwuji.mp4", locaPath2, remoteUrl2); 57 actionQueue.Enqueue(action2); 58 59 } 60 61 void OnUpdate() 62 { 63 while (true) 64 { 65 lock (lockObject) 66 { 67 if (actionQueue.Count > 0) 68 { 69 DownloadAction action = actionQueue.Dequeue(); 70 DownloadFile(action); 71 72 Debug.Log("开始下载文件:" + action.actionParams[0]); 73 Debug.Log("本地地址:" + action.actionParams[1]); 74 Debug.Log("远程地址:" + action.actionParams[2]); 75 } 76 } 77 Thread.Sleep(10); 78 } 79 } 80 81 /// <summary> 82 /// 下载文件 83 /// </summary> 84 /// <param name="action">下载任务</param> 85 private void DownloadFile(DownloadAction action) 86 { 87 //url 88 string localPath = action.actionParams[1].ToString(); 89 string remoteUrl = action.actionParams[2].ToString(); 90 91 WebClient client = new WebClient(); 92 clientList.Add(client); 93 94 //sw.Start(); //计时器,可以用于计算下载速度 95 client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProcesChange); 96 client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadComplete); 97 client.DownloadFileAsync(new Uri(remoteUrl), localPath); 98 } 99 100 /// <summary> 101 /// 异常处理回调 102 /// </summary> 103 private void DownloadComplete(object sender, AsyncCompletedEventArgs e) 104 { 105 if (e.Error != null) 106 { 107 Debug.LogError(e.Error.Message); 108 MemoryRelease(); 109 } 110 } 111 112 /// <summary> 113 /// 下载回调 114 /// </summary> 115 private void DownloadProcesChange(object sender, DownloadProgressChangedEventArgs e) 116 { 117 string received = (e.BytesReceived / (1024d * 1024d)) + ""; 118 Debug.Log("接收文件大小:" + received + "M"); 119 if (e.ProgressPercentage == 100 && e.BytesReceived == e.TotalBytesToReceive) 120 { 121 Debug.Log("下载完成"); 122 ((WebClient)sender).CancelAsync(); 123 ((WebClient)sender).Dispose(); 124 } 125 } 126 127 void OnApplicationQuit() 128 { 129 MemoryRelease(); 130 } 131 132 /// <summary> 133 /// 内存释放 134 /// </summary> 135 void MemoryRelease() 136 { 137 for (int i = 0; i < clientList.Count; i++) 138 { 139 clientList[i].CancelAsync(); 140 clientList[i].Dispose(); 141 } 142 } 143 }