WWW类封装

思考并回答以下问题:

进程、线程、协程

进程:

1、任何一个exe都是一个进程,有独立的用户空间,不能被其他的进程调用。
2、进程之间通过udo通信。

线程:
可理解成while(true)循环

1
2
3
4
while(true)
{
sleep(0.5); // 休息的时候执行其他的线程
}

最大速度的并发:Cpu核数 * 2

协程:

WWW类的功能

1、通过http或https协议,发起get或post请求;
2、加载本地文件。

资源的更新流程:

  • 1、对比版本;
  • 2、服务器会告诉客户端有多少个zip;
  • 3、客户端下载,解压到本地;
  • 4、程序去加载。

封装成迅雷这样的,下载地址往里一丢就自动处理下载,下载后弹出一个消息出来。

找到任务相同点,抽象出父类:

  • 1、都可以用www可以下载(协程)。
  • 2、下载完成,通知上层逻辑。
  • 3、下载失败,重新下载。

抽象下载器:

  • 1、无限的添加下载。
  • 2、队列里面主要有任务,就应该去下载。没有任务就不启动。

WWWItem.cs 父类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WWWItem
{
// 下载地址
private string url;

public string URL
{
get
{
return url;
}
set
{
url = value;
}
}

// 下载完成后要执行的事情留给子类自己处理
public virtual void DownLoadFinish(WWW www)
{

}

// 由子类处理出错
public virtual void DownLoadError(WWWItem wwwItem)
{

}

public virtual void BeginDownLoad()
{

}

// 协程
public IEnumerator DownLoad()
{
WWW www = new WWW(URL);

BeginDownLoad();

yield return www;

// 下载完成后
if(string.IsNullOrEmpty(www.error))
{
// 不处理逻辑,逻辑交给子类处理
DownLoadFinish(www);
}
else
{
Debug.LogError(www.error);
// 出错处理交给子类
DownLoadError(this);
}
}
}

WWWHelper.cs 无限下载器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WWWHelper : MonoBehaviour
{
// 单例
public static WWWHelper Instance;

// 先进先出
// 存放任务
Queue<WWWItem> downQueue;

void Awake()
{
Instance = this;
}

void Start()
{
downQueue = new Queue<WWWItem>();
}

// 此Flag解决漏洞
// 已经下载完成了,出队列了,yield return item.DownLoad();还没完成
// downQueue.Enqueue(item);又进来一个任务,又会启动一个协程
bool IsFinish = true;

// 给外界提供的接口,添加任务
public void AddTask(WWWItem item)
{
downQueue.Enqueue(item);

// 是否队列里面有任务
// != 1是还没有下载完成
if (downQueue.Count == 1 && IsFinish)
{
IsFinish = false;
// 有任务就启动协程
StartCoroutine(DownLoad());
}
}

public IEnumerator DownLoad()
{
// 只要队列里面有任务,就无限下载
while(downQueue.Count > 0)
{
// 出队列
WWWItem item = downQueue.Dequeue();

// 实现下载
// 协程套协程
// 可以看成两个for循环
yield return item.DownLoad();
}

IsFinish = true;
}
}

WWWTxt.cs 专门下载txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 继承WWWItem
public class WWWTxt : WWWItem
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="">传递Asset目录以下的目录</param>
public WWWTxt(string path)
{
path = Application.dataPath + path;
InitPath(path);
}

public override void DownLoadError(WWWItem item)
{
// 出错了再往里面丢
WWWHelper.Instance.AddTask(item);
}

public override void DownLoadFinish(WWW www)
{
Debug.Log("Process text == " + www.text);
}

public override void BeginDownLoad()
{
Debug.Log("begin DownLoad");
}

// 初始化路径
// 下载本地文件,需要路径
public void InitPath(string path)
{
if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer )
{
this.URL = "file:///" + path;
} else if (Application.platform == RuntimePlatform.Android)
{
this.URL = "file:///" + path;
}else
{
this.URL = "file//" + path;
}
}
}

UseWWWHelper.cs 客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UseWWWHelper : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
WWWTxt tmpItem = new WWWTxt("UI/Blood/Blood.cs");
WWWHelper.Instance.AddTask(tmpItem);
}
}
}
0%