【问题标题】:Titanium Preloading Images钛预加载图像
【发布时间】:2015-04-08 20:28:11
【问题描述】:

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

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

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

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

谢谢

【问题讨论】:

    标签: titanium titanium-mobile


    【解决方案1】:

    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);
    }
    

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

    【讨论】:

    • 拜托,@Jeff Bonnes,你能告诉我第一句话是什么意思吗?更新版本的 Titanium 是否允许您“本地”缓存图像,而无需编写大量代码?我有兴趣
    • 是的 - SDK > 3 的版本似乎无需任何额外代码即可缓存图像。请参阅下面的答案。
    • @JeffBonnes 看来内置图像缓存不再适用于 android > 6 。每次设置图像属性时,都会重新加载远程图像。
    【解决方案2】:

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

    从 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);
    

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 当然,完成我的回答。谢谢马克。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2015-08-12
    • 2018-12-22
    相关资源
    最近更新 更多