查看: 1097|回复: 0
打印 上一主题 下一主题

[经验分享] Unity+NGUI打造网络图片异步加载与本地缓存工具类(二)

[复制链接]

100

主题

3

听众

7683

积分

高级设计师

Rank: 6Rank: 6

纳金币
2378
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2015-2-15 16:38:47 |只看该作者 |倒序浏览

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

publicvoid SetAsyncImage(string url,UITexture texture)


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




publicvoid 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)

IEnumeratorDownloadImage(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类读取,但是这个过程是本地的还是比较快



IEnumeratorLoadLocalImage(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 {


publicTexture placeholder;

public static AsyncImageDownloadInstance=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;


}



publicvoid SetAsyncImage(string url,UITexture texture){




//开始下载图片前,将UITexture的主图片设置为占位图

texture.mainTexture = placeholder;


//判断是否是第一次加载这张图片


if (!File.Exists (path + url.GetHashCode())) {

//如果之前不存在缓存文件



StartCoroutine (DownloadImage (url, texture));



}

else {


StartCoroutine(LoadLocalImage(url,texture));


}


}


IEnumeratorDownloadImage(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;


}


IEnumeratorLoadLocalImage(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;


}

}


分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2025-7-23 04:55 , Processed in 0.066742 second(s), 28 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部