Unity+NGUI打造网络图片异步加载与本地缓存工具类|二

Unity+NGUI打造网络图片异步加载与本地缓存工具类|二

接上文,我们的工具类中的主要方法:

public void SetAsyncImage(string url,UITexture texture)

按照前文分析的图片加载步骤来


public  void SetAsyncImage(string url,UITexture texture){//开始下载图片前,将UITexture的主图片设置为占位图texture.mainTexture = placeholder;//判断是否是第一次加载这张图片if (!File.Exists (path + url.GetHashCode())) {//如果之前不存在缓存文件StartCoroutine (DownloadImage (url, texture));}else {StartCoroutine(LoadLocalImage(url,texture));}}

这里判断缓存文件是否存在使用的是url.GetHashCode()方法,因为我们的图片文件名采用的是原URL的哈希码直接作为文件名来保存,重名概率可以忽略不计,也缩短了文件名的长度提高效率,这个做法借鉴于 iOS开源框架EGOImageView。

如果是第一次加载图片,这个URL对应的文件不存在,那么我们就去原URL下载图片然后赋值给控件

如果缓存文件夹中已有该文件,直接读取加载

由于前文的铺垫,我们的工具类已经是MonoBehaviour的单例子类,所以可以使用unity的异步函数StartCorutine()


接下来完成方法DownloadImage(string url,UITexture texture)

IEnumerator  DownloadImage(string url,UITexture texture){Debug.Log("downloading new image:"+path+url.GetHashCode());  WWW www = new WWW (url);yield return www;Texture2D image = www.texture;//将图片保存至缓存路径byte[] pngData = image.EncodeToPNG();  File.WriteAllBytes(path+url.GetHashCode(), pngData);  texture.mainTexture = image;}


这个方法很简单,然后是从缓存文件夹读取已经存在的图片方法LoadLocalImage(string url,UITexture texture)

注意这里不能使用Resources.Load()方法,因为我们的图片并没有存放在工程目录中,我仔细查阅了相关资料发现比较合适的方法应该还是使用unity的WWW类去加载文件url,即在文件路径的前方加上file:///使之成为一个文件url,然后使用www类读取,但是这个过程是本地的还是比较快


IEnumerator  LoadLocalImage(string url,UITexture texture){string filePath = "file:///" + path + url.GetHashCode ();Debug.Log("getting local image:"+filePath);WWW www = new WWW (filePath);yield return www;//直接贴图texture.mainTexture = www.texture;}


我们的工具类写好了

随便找个Panel添加一个带UITexture组件的节点,然后调用我们的工具方法,测试下运行结果:

第一次运行:



打开这个文件所在的文件夹(我这里使用的是windows系统,不同系统路径不一样)




这个图片已经加载在我们的图片控件上并且已经保存至了本地路径,也就是说我们再次运行之后,不会再进入if的第一种情况了,我们关掉程序再次运行:



正如我们所想,实际上这次是没有产生网络请求的,说明我的缓存已经有用,而且图片一下就出来了,不像上一次要等一会



接下来我们删掉缓存文件再次执行,又会调用第一个方法~

这个工具类先做到这里了,接下来图片切换效果已经加载过程的等待HUD等后面再研究。完整代码:

using UnityEngine;using System.Collections;using System.IO;public class AsyncImageDownload :MonoBehaviour {public  Texture placeholder;public static AsyncImageDownload  Instance=null;private   string path=Application.persistentDataPath+"/ImageCache/" ;//构建单例public static AsyncImageDownload CreateSingleton(){if (!Directory.Exists(Application.persistentDataPath+"/ImageCache/")) {Directory.CreateDirectory(Application.persistentDataPath+"/ImageCache/");}GameObject obj = new GameObject ();obj.AddComponent<AsyncImageDownload> ();AsyncImageDownload loader= obj.GetComponent<AsyncImageDownload>();Instance=loader;loader.placeholder=Resources.Load("placeholder") as Texture;return loader;}public  void SetAsyncImage(string url,UITexture texture){//开始下载图片前,将UITexture的主图片设置为占位图texture.mainTexture = placeholder;//判断是否是第一次加载这张图片if (!File.Exists (path + url.GetHashCode())) {//如果之前不存在缓存文件StartCoroutine (DownloadImage (url, texture));}else {StartCoroutine(LoadLocalImage(url,texture));}}IEnumerator  DownloadImage(string url,UITexture texture){Debug.Log("downloading new image:"+path+url.GetHashCode());WWW www = new WWW (url);yield return www;Texture2D image = www.texture;//将图片保存至缓存路径byte[] pngData = image.EncodeToPNG();  File.WriteAllBytes(path+url.GetHashCode(), pngData);  texture.mainTexture = image;}IEnumerator  LoadLocalImage(string url,UITexture texture){string filePath = "file:///" + path + url.GetHashCode ();Debug.Log("getting local image:"+filePath);WWW www = new WWW (filePath);yield return www;//直接贴图texture.mainTexture = www.texture;}}

推荐阅读

    1394连接是什么1394网络适配器知识

    1394连接是什么1394网络适配器知识,,今天有网友在QQ群中问了这样一个问题:1394连接是什么?。由于笔者对1394连接不清楚,通过百度搜索与谷歌

    无线路由器网络如何自动断开线路

    无线路由器网络如何自动断开线路,,如何解决无线路由器网络自动断线?大家应该知道无线网络是很方便的,但是就是网络方面相对来说没那么稳定,对

    网络设置教程|如何网络设置

    网络设置教程|如何网络设置,,如何网络设置wifi路由器信道的设置步骤如下:1.打开浏览器,输入192.168.1.1,进入路由器的网关页面。2.输入管理员

    陈天乔:盛大网络为移动互联网

    陈天乔:盛大网络为移动互联网,,12月2日,北京时间,简称:盛大发布的2011财年第三季度财务报告,截至9月30日,在随后的电话会议上,盛大网络董事长和陈

    无法打开网络正常网页的解决方案

    无法打开网络正常网页的解决方案,,昨天我在一家电脑公司做了一个奇怪的现象,在网络的开始都是正常的,QQ是正常的,但不久之后,我发现无法打开网

    路由网络共享设置

    路由网络共享设置,,互联网已经与人们的生活息息相关,但是高昂的入网费用却成了不少人的负担(特别对于广大的莘莘学子),某些网络供应商还会限制

    vivo网络设置代码|vivo功能代码

    vivo网络设置代码|vivo功能代码,,1. vivo功能代码代码是*#558#1.首先在手机桌面里找到电话。2.在拨号键盘里输入*#558#3.这时候就进入了手