GameFramework下载器Download
类图
使用
先在 DownloadComponent 中配置:
- Download Agent Helper Count 下载器数量
public class TestDownload
{
static int s_downloadId;
public static void Test()
{
Game.Event.Subscribe(DownloadStartEventArgs.EventId, OnDownloadStart);
Game.Event.Subscribe(DownloadUpdateEventArgs.EventId, OnDownloadUpdate);
Game.Event.Subscribe(DownloadSuccessEventArgs.EventId, OnDownloadSuccess);
Game.Event.Subscribe(DownloadFailureEventArgs.EventId, OnDownloadFailure);
DownloadComponent downloadComponent = GameEntry.GetComponent<DownloadComponent>();
s_downloadId = downloadComponent.AddDownload(Path.Combine(Application.persistentDataPath,"1.txt")
, "http://myname.com/data/1.txt"
, userData: "mydown"); // userData 可以关联你自己的数据
}
private static void OnDownloadSuccess(object sender, GameEventArgs e)
{
// 下载成功
DownloadSuccessEventArgs args = (DownloadSuccessEventArgs)e;
// 有2种方式判断这个下载是不是你要的下载
// 1. GameFramework内置方式,通过 SerialId 判断
if ( args.SerialId != s_downloadId )
return ;
// 2. 你在用户数据中传递一个唯一的索引进行判断
if ( !(args.UserData is string name && name == "mydown") )
return ;
}
private static void OnDownloadFailure(object sender, GameEventArgs e)
{
DownloadFailureEventArgs args = (DownloadFailureEventArgs)e;
// 判断是否你的下载,同 OnDownloadSuccess
Debug.Log(args.ErrorMessage);
}
private static void OnDownloadStart(object sender, GameEventArgs e)
{
DownloadStartEventArgs args = (DownloadStartEventArgs)e;
}
private static void OnDownloadUpdate(object sender, GameEventArgs e)
{
DownloadUpdateEventArgs args = (DownloadUpdateEventArgs)e;
// 一般用来更新进度条,可是 args 只提供 CurrentLength 表示当前大小,没有总大小
}
}
流程分析
DownloadManager 管理下载,往 TaskPool<DownloadTask> 中添加下载任务 DownloadTask
TaskPool<DownloadTask> 负责找到空闲的下载器 DownloadAgent 来下载 DownloadTask
DownloadAgent 把具体的下载任务委托给 DownloadAgentHelperBase 去下载
UnityWebRequestDownloadAgentHelper 是 DownloadAgentHelperBase 的一个默认实现,把下载任务委托给 UnityWebRequest
下载代码分析
// 初始化下载器
DownlaodComponent.Start()
{
for (int i = 0; i < m_DownloadAgentHelperCount; i++)
{
AddDownloadAgentHelper(i)
{
// 这里创建的是 UnityWebRequestDownloadAgentHelper
DownloadAgentHelperBase downloadAgentHelper = Helper.CreateHelper(m_DownloadAgentHelperTypeName, m_CustomDownloadAgentHelper, index);
m_DownloadManager.AddDownloadAgentHelper(downloadAgentHelper) // DownloadManager.AddDownloadAgentHelper
{
DownloadAgent agent = new DownloadAgent(downloadAgentHelper);
agent.DownloadAgentStart += OnDownloadAgentStart;
agent.DownloadAgentUpdate += OnDownloadAgentUpdate;
agent.DownloadAgentSuccess += OnDownloadAgentSuccess;
agent.DownloadAgentFailure += OnDownloadAgentFailure;
m_TaskPool.AddAgent(agent)
{
agent.Initialize();
m_FreeAgents.Push(agent); // 加入空闲队列中
}
}
}
}
}
// 添加下载任务
DownlaodComponent.AddDownload(string downloadPath, string downloadUri)
{
return m_DownloadManager.AddDownload(downloadPath, downloadUri, tag, priority, userData) // DownloadManager.AddDownload
{
DownloadTask downloadTask = DownloadTask.Create(downloadPath, downloadUri, tag, priority, m_FlushSize, m_Timeout, userData);
m_TaskPool.AddTask(downloadTask) // TaskPool<DownloadTask>.AddTask
{
m_WaitingTasks.AddAfter(current, task); // 任务加入等待队列
}
return downloadTask.SerialId;
}
}
// 执行下载任务
DownloadManager.Update(float elapseSeconds, float realElapseSeconds)
{
m_TaskPool.Update(elapseSeconds, realElapseSeconds) // TaskPool<DownloadTask>.Update
{
ProcessRunningTasks(elapseSeconds, realElapseSeconds)
{
DownloadAgent taskAgent = m_WorkingAgents.First;
taskAgent.Update(elapseSeconds, realElapseSeconds)
{
// 判断正在下载的任务是否超时
}
}
ProcessWaitingTasks(elapseSeconds, realElapseSeconds) // TaskPool<DownloadTask>.ProcessWaitingTasks
{
LinkedListNode<DownloadTask> current = m_WaitingTasks.First; // 从等待列表中取出第1个任务
DownloadTask task = current.Value;
ITaskAgent<DownloadTask> agent = m_FreeAgents.Pop(); // 获得空闲下载任务执行器
LinkedListNode<ITaskAgent<DownloadTask>> agentNode = m_WorkingAgents.AddLast(agent); // 加入执行器列表中
StartTaskStatus status = agent.Start(task); // 用执行器下载任务
}
}
}