Unity使用C#网络下载用户头像
其实每个人中都会遇到在项目下载用户头像,下面是项目中使用的网络下载图片,使用WWW从网络上下载到本地,本地获取图片,使用的Unity版本是2017.1,使用UGUI
封装UnityEngine.WWW进行下载的类DownloadWWW .cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Linq;
using UnityEngine;
/// <summary>
/// 封装UnityEngine.WWW进行下载的类
/// </summary>
public class DownloadWWW : MonoBehaviour
{
private static DownloadWWW instance;
public static DownloadWWW Instance
{
get
{
if (instance == null)
{
GameObject obj = new GameObject();
//obj.name = "DownloadWWW";
instance = obj.AddComponent<DownloadWWW>();
}
return instance;
}
}
private void Awake()
{
DontDestroyOnLoad(gameObject);
}
/// <summary>
/// 下载url资源的文本内容
/// </summary>
/// <param name="url">url资源</param>
/// <param name="isAddRandomParams">是否添加随机参数</param>
/// <param name="callback">下载完毕回调函数</param>
/// <param name="retryCount">本次下载失败后的重试次数</param>
public void DownloadText(string url, bool isAddRandomParams, Action<bool, string> callback, Action<float> progress, int retryCount)
{
if (isAddRandomParams)
url = GetRandomParamsUrl(url);
Debug.Log("URL:" + url);
StartCoroutine(DoDownloadText(url, callback, progress, retryCount));
}
private IEnumerator DoDownloadText(string url, Action<bool, string> callback, Action<float> progress, int retryCount)
{
var www = new WWW(url);
while (!www.isDone)
{
if (progress != null)
progress(www.progress);
yield return null;
}
if (progress != null)
progress(www.progress);
if (string.IsNullOrEmpty(www.error))
{
if (callback != null)
callback(true, www.text);
}
else
{
if (retryCount <= 0)
{
// 彻底失败
Debug.LogError(string.Concat("DownloadText Failed! URL: ", url, ", Error: ", www.error));
if (callback != null)
callback(false, null);
}
else
{
// 继续尝试
yield return StartCoroutine(DoDownloadText(url, callback, progress, --retryCount));
}
}
}
/// <summary>
/// 下载url资源的字节内容
/// </summary>
/// <param name="url">url资源</param>
/// <param name="isAddRandomParams">是否添加随机参数</param>
/// <param name="callback">下载完毕回调函数</param>
/// <param name="retryCount">本次下载失败后的重试次数</param>
public void DownloadBytes(string url, bool isAddRandomParams, Action<bool, byte[]> callback, Action<float> progress, int retryCount)
{
if (isAddRandomParams)
url = GetRandomParamsUrl(url);
Debug.Log("URL:" + url);
StartCoroutine(DoDownloadBytes(url, callback, progress, retryCount));
}
private IEnumerator DoDownloadBytes(string url, Action<bool, byte[]> callback, Action<float> progress, int retryCount)
{
var www = new WWW(url);
while (!www.isDone)
{
if (progress != null)
progress(www.progress);
yield return null;
}
if (progress != null)
progress(www.progress);
if (string.IsNullOrEmpty(www.error))
{
if (callback != null)
callback(true, www.bytes);
}
else
{
if (retryCount <= 0)
{
// 彻底失败
Debug.LogError(string.Concat("DownloadBytes Failed! URL: ", url, ", Error: ", www.error));
if (callback != null)
callback(false, null);
}
else
{
// 继续尝试
yield return StartCoroutine(DoDownloadBytes(url, callback, progress, --retryCount));
}
}
}
/// <summary>
/// 给原始url加上随机参数
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private string GetRandomParamsUrl(string url)
{
var r = new System.Random();
var u = string.Format("{0}?type={1}&ver={2}&sign={3}", url.Trim(), r.Next(100), r.Next(100), Guid.NewGuid().ToString().Substring(0, 8));
return u;
}
/// <summary>
/// 访问http
/// </summary>
/// <param name="url"></param>
/// <param name="onDone"></param>
/// <param name="onFail"></param>
public void GetHttp(string url, Action<string> onDone, Action<string> onFail)
{
Debug.Log("URL:" + url);
StartCoroutine(DoGetHttp(url, onDone, onFail));
}
private IEnumerator DoGetHttp(string url, Action<string> onDone, Action<string> onFail)
{
WWW www = new WWW(url);
yield return www;
if (string.IsNullOrEmpty(www.error))
{
onDone(www.text);
}
else
{
Debug.Log("HttpResponse onFail:" + www.error);
onFail(www.error);
}
}
}
HTTP下载HttpManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.IO;
using System;
using System.Text;
using UnityEngine.UI;
/// <summary>
/// HTTP下载
/// </summary>
public class HttpManager : MonoBehaviour {
private static HttpManager instance;
public static HttpManager Instance
{
get
{
if (instance == null)
{
GameObject obj = new GameObject();
obj.name = "HttpManager";
instance = obj.AddComponent<HttpManager>();
}
return instance;
}
}
/// <summary>
/// web下载物体
/// </summary>
private GameObject webDownloaderObj;
/// <summary>
/// 下载类
/// </summary>
private DownloadWWW downloadWWW;
/// <summary>
/// 缓存字典
/// </summary>
private Dictionary<string, Texture2D> dicHeadTextureMd5;
/// <summary>
/// 下载的图相list
/// </summary>
private List<string> lisHeadName;//预备下载图像清单
//private void Awake()
//{
//}
void Start () {
Init();
}
public void Init()
{
webDownloaderObj = new GameObject("WebDownloader");
downloadWWW = webDownloaderObj.AddComponent<DownloadWWW>();
dicHeadTextureMd5 = new Dictionary<string, Texture2D>();
}
/// <summary>
/// 手机内存读取图片
/// </summary>
public Texture2D LoadTexture2DInStorage(string url)
{
//创建文件读取流
FileStream fileStream = new FileStream(url, FileMode.Open, FileAccess.Read);
fileStream.Seek(0, SeekOrigin.Begin);
//创建文件长度缓冲区
byte[] bytes = new byte[fileStream.Length];
//读取文件
fileStream.Read(bytes, 0, (int)fileStream.Length);
//释放文件读取流
fileStream.Close();
fileStream.Dispose();
fileStream = null;
//创建Texture
int width = 50;
int height = 50;
Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);
texture.LoadImage(bytes);
return texture;
}
/// <summary>
/// 字典初始化
/// </summary>
private void InitTempTextture()
{
if (dicHeadTextureMd5 == null)
{
dicHeadTextureMd5 = new Dictionary<string, Texture2D>();
}
}
/// <summary>
/// 清单初始化
/// </summary>
private void InitTempLisName()
{
if (lisHeadName == null)
lisHeadName = new List<string>();
}
/// <summary>
/// 检测字典是否包含该图片
/// </summary>
/// <param name="textureName"></param>
/// <returns></returns>
public bool IshaveTempTextture(string textureName)
{
return (dicHeadTextureMd5.ContainsKey(textureName));
}
/// <summary>
/// 临时存储图片到字典
/// </summary>
/// <param name="textureName"></param>
/// <param name="texture2D"></param>
public void SaveTempDicTextture(string textureName, Texture2D texture2D)
{
if (!dicHeadTextureMd5.ContainsKey(textureName))
dicHeadTextureMd5.Add(textureName, texture2D);
}
/// <summary>
/// 从字典读取图片
/// </summary>
/// <param name="textureName"></param>
/// <returns></returns>
public Texture2D LoadTempDicTextture(string textureName)
{
return dicHeadTextureMd5[textureName];
}
/// <summary>
/// 载入默认头像,并存入字典(临时存储)
/// </summary>
/// <returns></returns>
public Texture2D LoadDefaultTexture(string texNameMd5)
{
Texture2D defTex = Resources.Load<Texture2D>("Face/headdefault");//载入默认头像
SaveTempDicTextture(texNameMd5, defTex);//存入字典(临时存储)
return defTex;
}
public void LoadImage(string url,GameObject path)
{
RawImage rawImage = path.GetComponent<RawImage>();
if (rawImage != null)
{
StartCoroutine(LoadHead(url, rawImage));
}
}
/// <summary>
/// 头像加载
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public IEnumerator LoadHead(string url, RawImage logo)
{
int tryCount = 0;
while (tryCount < 10)//下载尝试次数
{
bool andios = (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer);
string texName = url;//图片名称.Remove(0, url.LastIndexOf("/") + 1)
string texNameMd5 = RegularExpression.MD5Encrypt32(texName);//图片名称加密md5
//Debug.Log(texName + " " + texNameMd5);+
string directoryPath = "";//图片文件夹路径
string directoryMd5Path = "";//图片文件完整路径
bool isLoad = false;//是否开始下载,否则读内存
InitTempTextture();
InitTempLisName();//初始化清单
if (!lisHeadName.Contains(texNameMd5))
{
lisHeadName.Add(texNameMd5);
isLoad = true;//不存在则添加入清单,并进入下载模式
}
yield return 0;//下一帧后检测全局
if (!isLoad)
{
float waitTime = 0;
while (!IshaveTempTextture(texNameMd5) && waitTime < 1.5f) { waitTime += Time.deltaTime; yield return 0; }//字典是否含该图片,等待快出现的内存
if (waitTime < 1.5f)
{
if(logo)
logo.texture = LoadTempDicTextture(texNameMd5);//显示//有则直接读取内存
}
else logo.texture = LoadDefaultTexture(texNameMd5);
tryCount = 10; break;//结束
}
else
{ //无则开始图片加载过程
if (andios)
{ ///手机无则创建文件夹
//directoryPath = "D:/" + "/headimage";//
directoryPath = Application.persistentDataPath + "/headimage";//文件夹路径
Debug.Log("<color=yellow>图片保存路径:::"+ directoryPath + "</color>");
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);//无则创建文件夹
while (!Directory.Exists(directoryPath)) { yield return 0; }//创建时间,检测文件夹是否存在
directoryMd5Path = directoryPath + "/" + texNameMd5;//图片文件完整路径
//读取手机内存中文件夹里的图片
if (File.Exists(directoryMd5Path))
{
Debug.Log("导入手机内存图片");
Texture2D newTex = LoadTexture2DInStorage(directoryMd5Path);//读取
logo.texture = newTex;//显示
Debug.Log("<color = #FFD505> +++++++ " + newTex.name + "+++++++++++++++++ </color> ");
SaveTempDicTextture(texNameMd5, newTex);//存入字典(临时存储)
tryCount = 10; break;//结束
}
}
if (!andios || (andios && !File.Exists(directoryMd5Path)))
{//从服务器下载图片后存入内存
if (url.Length <= 10)
{//长度不够则为无效url,载入默认头像
logo.texture = LoadDefaultTexture(texNameMd5);
tryCount = 10; break;//结束
}
else
{//长度够则为有效url,下载头像
WWW www = new WWW(url);
yield return www; Debug.Log("头像下载完毕");
if (string.IsNullOrEmpty(www.error))
{ //www缓存时有缺陷,2种方式存内存
Texture2D wwwTex = new Texture2D(www.texture.width, www.texture.height, TextureFormat.RGB24, false);
www.LoadImageIntoTexture(wwwTex);
//Texture2D wwwTex = www.texture;
logo.texture = wwwTex;//显示
SaveTempDicTextture(texNameMd5, wwwTex);//存入字典(临时存储)
if (andios && !File.Exists(directoryMd5Path)) WebTestDownload(url, directoryMd5Path);//存入手机内存
while (!File.Exists(directoryMd5Path)) { yield return 0; }
Texture2D newTex = LoadTexture2DInStorage(directoryMd5Path);//读取内置
SaveTempDicTextture(texNameMd5, newTex);//存入字典(临时存储)
tryCount = 10; break;//结束
}
else tryCount++;//重新下载尝试+1
}
}
}
}
}
/// <summary>
/// web下载
/// </summary>
/// <param name="url"></param>
/// <param name="isAddRandomParams"></param>
/// <param name="callback"></param>
/// <param name="progress"></param>
public void DownloadBytes(string url, bool isAddRandomParams = true, Action<bool, byte[]> callback = null, Action<float> progress = null)
{
if (downloadWWW == null) Init();
downloadWWW.DownloadBytes(url, isAddRandomParams, callback, progress, 3);
}
/// <summary>
/// 使用协程下载文件
/// </summary>
public void WebTestDownload(string url, string filepath)
{
//string url = "http://192.168.70.88:8000/Android/weekly/last/1001.prefab.k_d4a807497e976cbadd197c90160ef3ee";
DownloadBytes(url, true, (ok, bytes) =>
{
if (ok)
{
//string filepath = Application.persistentDataPath + "/1001.prefab.k";
File.WriteAllBytes(filepath, bytes);
Debug.Log("Download Success: " + filepath + ", " + File.Exists(filepath));
}
});
}
/// <summary>
/// 连接htttp请求 解析返回内容
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public string HttpGet(string url)
{
string str=null;
HttpWebRequest res = (HttpWebRequest)WebRequest.Create(url);
res.Method = "GET";
res.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)res.GetResponse();
Stream strRes = response.GetResponseStream();
StreamReader read = new StreamReader(strRes,Encoding.GetEncoding("utf-8"));
str = read.ReadToEnd();
Debug.Log(str);
strRes.Close();
read.Close();
return str;
}
}
怎么使用呢?只需要在场景中一个物体上挂载HttpManager.cs,
HttpManager httpManager = go.GetComponent《HttpManager》();//去它身上拿到HttpManager脚本
httpManager.LoadImage(imageURL, obj);//传入下载地址和需要改变图片的物体