首页 > 代码库 > [原]unity3d之http多线程异步资源下载

[原]unity3d之http多线程异步资源下载

郑重声明:转载请注明出处 U_探索

本文诞生于乐元素面试过程,被面试官问到AssetBundle多线程异步下载时,愣了半天,同样也被深深的鄙视一回(做了3年多u3d 这个都没用过),所以发誓要实现出来填补一下自己的空白,同时分享给大家。说明:本人只在pc和Android下测试好使,其他平台未知!

直接贴代码,都是C# http的API,不懂得自己百科。

using UnityEngine;using System.Collections;using System;using System.Text;using System.Net;using System.IO;internal class WebReqState{    public byte[] Buffer;        public FileStream fs;        public const int BufferSize = 1024;        public Stream OrginalStream;        public HttpWebResponse WebResponse;        public WebReqState(string path)    {        Buffer = new byte[1024];        fs = new FileStream(path,FileMode.Create);    }}public class HttpHelper {    string path = null;    string assetName;    public HttpHelper(string path)    {        this.path = path;    }        public  void AsyDownLoad(string url){    Debug.Log(url);    assetName = url.Split(/)[4];    Debug.Log(assetName);    HttpWebRequest httpRequest = WebRequest.Create(url) as HttpWebRequest;    httpRequest.BeginGetResponse( new AsyncCallback(ResponseCallback), httpRequest);}        void ResponseCallback(IAsyncResult ar){    HttpWebRequest req = ar.AsyncState as HttpWebRequest;    if(req == null) return;    HttpWebResponse response = req.EndGetResponse(ar) as HttpWebResponse;    if(response.StatusCode != HttpStatusCode.OK)    {        response.Close();        return;    }    Debug.Log(path+ "/"+assetName);    WebReqState st = new WebReqState(path+ "/"+assetName);    st.WebResponse = response;    Stream responseStream = response.GetResponseStream();    st.OrginalStream = responseStream;    responseStream.BeginRead(st.Buffer,0,WebReqState.BufferSize,new AsyncCallback(ReadDataCallback),st);}        void ReadDataCallback(IAsyncResult ar){    WebReqState rs = ar.AsyncState as WebReqState;    int read =rs.OrginalStream.EndRead(ar);    if(read>0)    {        rs.fs.Write(rs.Buffer,0,read);        rs.fs.Flush();        rs.OrginalStream.BeginRead(rs.Buffer, 0, WebReqState.BufferSize, new AsyncCallback(ReadDataCallback), rs);    }    else    {        rs.fs.Close();        rs.OrginalStream.Close();        rs.WebResponse.Close();        Debug.Log(assetName+":::: success");    }}}
View Code

下载部分:

if(GUI.Button(new Rect(0,0,100,30),"test")){    string rootPath = Application.persistentDataPath;//android上保存到 /storage/sdcard0/Android/data/包名(例如:com.example.test)/files    for(int i =0;i<str.Length;i++) //str是string型数组,存放部分assetbundle名字    {        Thread thread = new Thread(new ParameterizedThreadStart(DownAsset)); //ParameterizedThreadStart 多线程传参         thread.Start(rootPath+"|"+str[i]); //只能带一个object参数 所以使用字符串拼接    }}     void DownAsset(System.Object file){    string[] fileName = file.ToString().Split(|);    HttpHelper help = new HttpHelper(fileName[0]);    help.AsyDownLoad("http://192.168.0.103/unity/"+fileName[1]+".AssetBundle");//注意在手机上测试 该对Ip地址}

 

下载完成后 可以去/storage/sdcard0/Android/data/包名(例如:com.example.test)/files查找对应文件

加载部分:

if(GUI.Button(new Rect(0,30,100,30),"load")){    for(int i =0;i<str.Length;i++)    {        StartCoroutine(LoadAsset(str[i],i));    }}IEnumerator LoadAsset(string name,int i){    WWW w = new WWW("file://"+Application.persistentDataPath+"/"+name+".AssetBundle");    yield return w;    Instantiate(w.assetBundle.mainAsset,new Vector3(i*2,0,0),Quaternion.identity);    w.assetBundle.Unload(false);}

 

注意事项:

1、pc测试 需要修改IP地址,本地测试改为127.0.0.1 同时Application.persistentDataPath最好做修改,因为在pc上Application.persistentDataPath:C:\Users\用户名\AppData\LocalLow\DefaultCompany\u3d工程名,可以下载到此文件夹下,但是加载的时候会报错,没什么权限之类的

2、android上需要stripping level设置为Disabled