1

我想知道 Titanium 如何处理图像。如果我要在图像视图中加载图像,然后将图像视图中的图像更改为本地图像,然后将图像更改回以前的图像,图像视图是否需要再次下载以前的图像?

不确定 Titanium 如何处理下载的图像,但我认为它不会缓存它们。

我在想我可以创建一些屏幕外图像并将其他一些图像视图设置为他们的图像 url,但这会工作吗?或者图像视图会下载图像吗?

只是想弄清楚图像视图如何在钛中工作,以及确保我可以预加载/重用图像的最佳方法。

谢谢

4

2 回答 2

7

2015 年 4 月更新:从 Titanium 3.X 开始,根据 Gautier 的回答,图像中有缓存


默认情况下,ImageView 中没有缓存远程图像。在您的场景中,当您切换回远程图像时,它将再次重新下载。

在我的大多数项目中,我创建了一个缓存图像视图,用于在下载后保存本地图像。这是受到 Dawson Toth 在https://gist.github.com/938172上的工作的启发。唯一的问题是,如果图像在本地缓存后在服务器上发生更改,除非文件名更改,否则客户端不会获得更新的图像。代码如下。

exports.createCachingImageView = function(params) {
    var image = Ti.UI.createImageView();

    image.doRemote = function(imageURL) {
        image.remoteImage = imageURL;
        var file = Ti.Filesystem.getFile(somedirectory, image.localFileName(imageURL));

        if(!file.exists()) {
             // cached file does not exist, load the image
            image.addEventListener("load", image.saveImageOnLoad);
            image.image = imageURL;
        } else {
            Ti.API.debug(image.localFileName(imageURL) + ' does exist, just setting image');
            image.image = file.nativePath;
        }
    };

    image.saveImageOnLoad = function(e) {
        Ti.API.debug('saving image ' + image.localFileName(image.remoteImage));
        var f = Ti.Filesystem.getFile(somedirectory, image.localFileName(image.remoteImage));
        if(!f.read()) {
            f.write(e.source.toBlob());
        }
        e.source.removeEventListener('load', image.saveImageOnLoad);
    };

    image.localFileName = function(imageURL) {
        hashedSource = Ti.Utils.md5HexDigest(imageURL + '');
        return hashedSource;
    };
    if(params.image) {
        image.doRemote(params.image);
    }

    for(var v in params) {
        if(v != 'image') {
            image[v] = params[v];
        }
    }

    return image;
};

如果您想在不使用 imageView 的情况下单独下载图像,请使用 Ti.Network.httpClient 获取图像并将其保存到文件系统,如下所示:

xhr.onload = function(){    
  var file = Ti.Filesystem.getFile(somedirectory, somefilename );
  file.write(this.responseData);
}

我使用它来提前获取图像,因此当客户使用它们时它们应该立即。

于 2012-07-09T00:00:12.707 回答
0

挖掘出这个很老的问题,因为我必须做同样的事情。

从 Android 3.1 和 iOS 开始,现在有一个默认缓存:请参阅http://docs.appcelerator.com/titanium/latest/#!/guide/Image_Best_Practices-section-30082525_ImageBestPractices-Cachingremoteimages

在 Android 平台上,缓存限制为 25 MB,并且数据会在应用程序的整个生命周期内保留(只要它安装在设备上)。在 iOS 平台上,缓存大小不是预先确定的(无法保证大小),数据会一直保留在那里,直到 iOS 清理目录(需要更多的本地存储)。

该文档页面也有自己的图像手动缓存实现。

var Utils = {
  /* modified version of https://gist.github.com/1243697 */
  _getExtension: function(fn) {
    // from http://stackoverflow.com/a/680982/292947
    var re = /(?:\.([^.]+))?$/;
    var tmpext = re.exec(fn)[1];
    return (tmpext) ? tmpext : '';
  },
  RemoteImage: function(a){
    a = a || {};
    var md5;
    var needsToSave = false;
    var savedFile;
    if(a.image){
      md5 = Ti.Utils.md5HexDigest(a.image)+this._getExtension(a.image);
      savedFile = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,md5);
      if(savedFile.exists()){
        a.image = savedFile;
      } else {
        needsToSave = true;
      }
    }
    var image = Ti.UI.createImageView(a);
    if(needsToSave === true){
      function saveImage(e){
        image.removeEventListener('load',saveImage);
        savedFile.write(
          Ti.UI.createImageView({image:image.image,width:'auto',height:'auto'}).toImage()
        );
      }
      image.addEventListener('load',saveImage);
    }
    return image;
  }
};
// example usage
var image = Utils.RemoteImage({
  image:'http://farm7.staticflickr.com/6059/6262552465_e53bccbd52_z.jpg',
  defaultImage:'KS_nav_ui.png',
  width:300,
  height:200,
  top:20
});
win2.add(image);
于 2014-09-21T15:44:49.807 回答