【问题标题】:Universal-Image-Loader Custom FileNameGenerator based on local file nameUniversal-Image-Loader 自定义 FileNameGenerator 基于本地文件名
【发布时间】:2014-12-23 14:17:57
【问题描述】:

我正在使用通用图像加载器来显示从 URI 下载的图像或已在磁盘缓存实现中可用的图像。

我想显示音乐专辑封面,但多个曲目可能具有相同的封面 URI(即来自同一专辑的曲目)。即使图像相同,我也希望每次都为每个不同的轨道存储带有轨道名称的图像,因为我希望用户能够用自定义封面替换默认封面,即使对于每个单独的轨道也是如此。

例如

  • 01 - 曲目 01.mp3
  • 02 - 曲目 02.mp3

属于同一张专辑,封面URI是http://something/img.jpg,磁盘缓存上我想拥有

  • 01 - 曲目 01.jpg
  • 02 - 曲目 02.jpg

即使是同一张图片。

所以我编写了一个FileNameGenerator,它为每个Uri 存储了一个Set 的哈希值,其中哈希值是文件绝对路径的SHA-1。

这是我的实现:

public MyFileNameGenerator(String ext) {
    super();
    this.ext = ext;
}

HashMap<String,HashSet<String>> names = new HashMap<String, HashSet<String>>();

@Override
public String generate(String imageUri) {
    if(imageUri==null) return null;
    if (imageUri.startsWith("file:///")) {
        return FilenameUtils.removeExtension(Uri.parse(imageUri)
                .getLastPathSegment()) + "."+ext;
    }
    //How to recognize the correct hash?
    //return FilenameUtils.removeExtension(Data.currentFiles
    //      .get(names.get(imageUri)).getName()) + "." + ext;
}

public void setTrackData(String uri, String hash) {
    if(!names.containsKey(uri))
        names.put(uri, new HashSet<String>());
    names.get(uri).add(hash);
}

但我走入了死胡同,因为无法理解我正在为哪个文件显示图像,因为 generate 仅将 imageURI 作为参数,并且更多哈希可以属于同一个 uri。

我该如何规避这个问题?

【问题讨论】:

  • 我不太清楚,所以您希望 track_name.mp3 作为哈希的键,而 track_name.jpg 作为值?如果是这种情况,只需将album_name添加到键[album_name_terack_name.mp3=track_name.jpg],这样就可以区分同名的曲目,相同的值没有问题
  • @Yazan 没有。两个不同的文件可以有相同的图像uri(即相同的专辑封面),我为每个uri存储一组哈希,哈希是mp3文件绝对路径的SHA1,这样我就知道给定的uri被某些文件使用.调用 generate 时,它​​应该返回 mp3 的名称,但带有 png 扩展名。但是由于generate 只将uri 作为参数,我怎么知道我正在为哪个文件显示图像?换句话说,同一个 URI 应该根据我为其显示封面的文件加载不同的图像。
  • 好的,为什么不反过来使用呢?使用 track_name.mp3 作为 key,这样,除非用户更改图像,否则哈希可以相同(具有相同的图像),因此名为 (track_name.mp3) 的条目将具有新的哈希(图像)
  • @Yazan 因为 generate 有 uri 作为参数,所以 uri 是关键,使用 uri 的文件是值。
  • 好的,我现在明白了,抱歉我意识到它与图像加载器有关 :)

标签: android universal-image-loader


【解决方案1】:

我想我已经找到了解决方案。

每当我调用我的ImageLoader 实例来显示图像时,我都会使用

if (uri != null && !uri.isEmpty()) {
    uri = Uri.parse(uri).buildUpon()
        .appendQueryParameter("myhashkeyparameter", "myHashValue").toString();
}
mImageLoader.displayImage(uri,mImageView);

这段代码会在一个有效的uri上附加一个查询参数,这个uri会变成:

http://someuri/image.jpg?myhashkeyparameter=myHashValue

然后在FileNameGeneratorgenerate方法中我可以使用

String hash = Uri.parse(imageUri).getQueryParameter("myhashkeyparameter");

在不依赖于使用 imageUri 作为键的情况下检索想要的文件。

完整代码:

@Override
public String generate(String imageUri) {
    if(imageUri==null||imageUri.isEmpty()) return "";
    if (imageUri.startsWith("file:///")) {
        return FilenameUtils.removeExtension(Uri.parse(imageUri)
                .getLastPathSegment()) + "."+ext;
    }
    String hash = Uri.parse(imageUri).getQueryParameter("myhashkeyparameter");
    if(null==hash||hash.isEmpty()) return "";
    if(Data.currentFiles.containsKey(hash)){
     return FilenameUtils.removeExtension(Data.currentFiles.get(hash).getName())+".png";
    }
    else return "";
}

您只需要注意用作查询参数的字符串尚未在 http URL 中使用,因此请避免使用传统名称,如 name、hash、h、title 等。

【讨论】:

    猜你喜欢
    • 2013-06-14
    • 2015-10-06
    • 2012-12-15
    • 1970-01-01
    • 2012-11-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    相关资源
    最近更新 更多