多文件下载,把文件加入链表中,下载中和下载结束后的委托
限定数目5个
开始下载
/// <summary>
/// 下载多个文件
/// </summary>
/// <param name="lstUrl"></param>
/// <param name="onUpdate"></param>
/// <param name="onComplete"></param>
internal void BeginDownloadMulit(LinkedList<string> lstUrl, BaseAction<int, int, ulong, ulong> onUpdate, BaseAction onComplete)
{
m_OnDownloadMulitUpdate = onUpdate;
m_OnDownloadMulitComplete = onComplete;
m_NeedDownloadList.Clear();
m_DownloadMulitCurrSizeDic.Clear();
m_DownloadMulitNeedCount = 0;
m_DownloadMulitCurrCount = 0;
m_DownloadMulitTotalSize = 0;
m_DownloadMulitCurrSize = 0;
//1.把需要下载的加入下载队列
for (LinkedListNode<string> item = lstUrl.First; item != null; item = item.Next)
{
string url = item.Value;
//下载的时候检测数据的合法性,能从Assetbunlle中拿到信息,说明是有效的
AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url);
if (entity != null)
{
//文件的总大小是通过打包的时候计算出来的
m_DownloadMulitTotalSize += entity.Size;
m_DownloadMulitNeedCount++;
//加到需要下载的文件链表中
m_NeedDownloadList.AddLast(url);
//对应的url中已经下载的大小
m_DownloadMulitCurrSizeDic[url] = 0;
}
else
{
GameEntry.LogError("无效资源包=>" + url);
}
}
//下载器数量限定为5个,下载的时候占带宽,下载的时候要写入内存,性能卡顿
int routineCount = Mathf.Min(GameEntry.Download.DownloadRoutineCount, m_DownloadMulitNeedCount);
for (int i = 0; i < routineCount; i++)
{
//从池中取下载器
DownloadRoutine routine = GameEntry.Pool.DequeueClassObject<DownloadRoutine>();
//拿到url
string url = m_NeedDownloadList.First.Value;
//从链表中剔除掉
AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url);
//执行下载器的下载,这个回调是所有下载器共用一个回调
routine.BeginDownload(url, entity, OnDownloadMulitUpdate, OnDownloadMulitComplete);
//然后加入到下载器链表中
m_DownloadRoutineList.AddLast(routine);
m_NeedDownloadList.RemoveFirst();
}
}
开始下载
/// <summary>
/// 开始下载,第二个参数的参数,地址,字节数,进度;第三个参数的参数,url和下载器
/// </summary>
/// <param name="url"></param>
/// <param name="onUpdate"></param>
/// <param name="onComplete"></param>
public void BeginDownload(string url, AssetBundleInfoEntity assetBundleInfo, BaseAction<string, ulong, float> onUpdate, BaseAction<string, DownloadRoutine> onComplete)
{
m_CurrFileUrl = url;
m_CurrAssetBundleInfo = assetBundleInfo;
m_OnUpdate = onUpdate;
m_OnComplete = onComplete;
m_DownloadLocalFilePath = string.Format("{0}/{1}", GameEntry.Resource.LocalFilePath, m_CurrFileUrl);
//如果本地已有目标文件, 则删除
if (File.Exists(m_DownloadLocalFilePath)) File.Delete(m_DownloadLocalFilePath);
//下载新版本的资源
m_DownloadLocalFilePath = m_DownloadLocalFilePath + ".temp";
if (File.Exists(m_DownloadLocalFilePath))
{
if (PlayerPrefs.HasKey(m_CurrFileUrl))
{
if (!PlayerPrefs.GetString(m_CurrFileUrl).Equals(assetBundleInfo.MD5, StringComparison.CurrentCultureIgnoreCase))
{
//根据MD5判断 跟CDN上的MD5不一致则删除原文件重新下载
File.Delete(m_DownloadLocalFilePath);
BeginDownload();
}
else
{
//断点续传_继续下载
m_FileStream = File.OpenWrite(m_DownloadLocalFilePath);
m_FileStream.Seek(0, SeekOrigin.End);
m_BeginPos = (uint)m_FileStream.Length;
Download(string.Format("{0}/{1}", GameEntry.Data.SysDataManager.CurrChannelConfig.RealSourceUrl, m_CurrFileUrl), m_BeginPos);
}
}
else
{
//本地没有MD5记录,重新下载
File.Delete(m_DownloadLocalFilePath);
BeginDownload();
}
}
else
{
BeginDownload();
}
}
/// <summary>
/// 从零下载
/// </summary>
private void BeginDownload()
{
string directory = Path.GetDirectoryName(m_DownloadLocalFilePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
m_FileStream = new FileStream(m_DownloadLocalFilePath, FileMode.Create, FileAccess.Write);
PlayerPrefs.SetString(m_CurrFileUrl, m_CurrAssetBundleInfo.MD5);
Download(string.Format("{0}/{1}", GameEntry.Data.SysDataManager.CurrChannelConfig.RealSourceUrl, m_CurrFileUrl));
}
/// <summary>
/// 从头下载下载
/// </summary>
/// <param name="url"></param>
private void Download(string url)
{
m_UnityWebRequest = UnityWebRequest.Get(url);
m_UnityWebRequest.SendWebRequest();
}
下载中
/// <summary>
/// 多文件下载中的委托
/// </summary>
/// <param name="url"></param>
/// <param name="currDownSize">当前的文件已经下载的大小</param>
/// <param name="progress"></param>
private void OnDownloadMulitUpdate(string url, ulong currDownSize, float progress)
{
m_DownloadMulitCurrSizeDic[url] = currDownSize;
ulong currSize = 0;
//计算所有文件下载的大小,循环字典然后累加
var enumerator = m_DownloadMulitCurrSizeDic.GetEnumerator();
while (enumerator.MoveNext())
{
currSize += enumerator.Current.Value;
}
m_DownloadMulitCurrSize = currSize;
if (m_DownloadMulitCurrSize > m_DownloadMulitTotalSize) m_DownloadMulitCurrSize = m_DownloadMulitTotalSize;
if (m_OnDownloadMulitUpdate != null)
{
//更新当前数量,总数量,当前大小总大小
m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize);
}
}
下载完之后的回调
private void OnDownloadMulitComplete(string fileUrl, DownloadRoutine routine)
{
//检查需要加载的文件列表中是否有要下载的数量
if (m_NeedDownloadList.Count > 0)
{
//让下载器继续工作
string url = m_NeedDownloadList.First.Value;
AssetBundleInfoEntity entity = GameEntry.Resource.ResourceManager.GetAssetBundleInfo(url);
routine.BeginDownload(url, entity, OnDownloadMulitUpdate, OnDownloadMulitComplete);
m_NeedDownloadList.RemoveFirst();
}
else
{
//没有需要下载的了,下载器从下载列表中移除并回池
m_DownloadRoutineList.Remove(routine);
GameEntry.Pool.EnqueueClassObject(routine);
}
//下载数量++
m_DownloadMulitCurrCount++;
//更新下载数量
if (m_OnDownloadMulitUpdate != null)
{
m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize);
}
//当前下载数量=总数量
if (m_DownloadMulitCurrCount == m_DownloadMulitNeedCount)
{
m_DownloadMulitCurrSize = m_DownloadMulitTotalSize;
//执行全部下载完毕的委托
if (m_OnDownloadMulitUpdate != null)
{
//所有文件下载完毕,最后一次执行更新委托
m_OnDownloadMulitUpdate(m_DownloadMulitCurrCount, m_DownloadMulitNeedCount, m_DownloadMulitCurrSize, m_DownloadMulitTotalSize);
}
if (m_OnDownloadMulitComplete != null) m_OnDownloadMulitComplete();
//Debug.LogError("所有资源下载完毕!!!");
}
}
生成版本文件的时候修改为ulong.
也修改为ulong