当本地存储中不存在文件时,Picasso 显示错误图像
Picasso is showing wrong image when file does not exists on local storage
我有一个回收站视图,其中显示了用户列表及其头像。登录后,我下载所有头像并将它们保存在本地,文件名是 mongo db 中用户的行 ID。当头像文件在存储中不可用时,Picasso 会随机加载其他用户的头像之一。我应该怎么做才能防止这种情况。
这是在不可用的情况下显示或下载图像的常用代码
我尝试在 Picasso 中使用缓存策略,但也没有用。
public ImageUtils loadFromDisk(String id, ImageView target) {
Log.d(TAG, "loadFromDisk: imageId: " + id);
File directory = contextWrapper.getDir("avatars", Context.MODE_PRIVATE);
File avatarPath = new File(directory, id);
if (avatarPath.exists()) {
Log.d(TAG, "loadFromDisk: loaded from disk" + avatarPath);
Picasso.get().load(avatarPath)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(target);
} else {
Picasso.get().load(R.drawable.image_thumb).into(target);
}
return this;
}
我从 RecyclerView bindView holder class 中的 Singleton ImageUtils class 调用 loadFromDisk。
PS: bindViewHolder代码
public void onBindViewHolder(@NonNull RecentChatsViewHolder recentChatsViewHolder, int i) {
Log.d(TAG, "onBindViewHolder: content row");
if (recentChat.isNew) {
recentChatsViewHolder.blueDot.setVisibility(View.VISIBLE);
} else {
recentChatsViewHolder.blueDot.setVisibility(View.GONE);
}
recentChatsViewHolder.avatar.setImageResource(R.drawable.ic_info_outline_white_48dp);
ImageUtils.getInstance(context).loadFromDisk(recentChat.id, recentChatsViewHolder.avatar); //this calls above function here I don't pass the else condition of above method so there's no race condition
}
由于这是在 recyclerView 中,我假设发生了某种竞争条件。当您调用 FileDownloader
下载一些图像时。它下载图像并将其加载到目标。但目标不正确,因为回收站视图现在已滚动。
也许,您可以通过将 id
作为标签添加到 ImageView
并在下载图像后检查标签来避免这种情况。如果标签不同,请不要将图像加载到视图中。 -> 这仅在下载 callback/lambda 通过 id
.
时有效
编辑:
我不知道 fallback
发生了什么。如果您能从您添加的片段中删除它会更好。
我可以提出两点建议。
ImageView.setImageBitmap(null)
或要求 Picasso 在加载新图像之前清除目标。如果头像不存在,请清空目标
- 添加
errorDrawable
,如果出现错误,将不会显示上一张图像。
我有一个回收站视图,其中显示了用户列表及其头像。登录后,我下载所有头像并将它们保存在本地,文件名是 mongo db 中用户的行 ID。当头像文件在存储中不可用时,Picasso 会随机加载其他用户的头像之一。我应该怎么做才能防止这种情况。 这是在不可用的情况下显示或下载图像的常用代码
我尝试在 Picasso 中使用缓存策略,但也没有用。
public ImageUtils loadFromDisk(String id, ImageView target) {
Log.d(TAG, "loadFromDisk: imageId: " + id);
File directory = contextWrapper.getDir("avatars", Context.MODE_PRIVATE);
File avatarPath = new File(directory, id);
if (avatarPath.exists()) {
Log.d(TAG, "loadFromDisk: loaded from disk" + avatarPath);
Picasso.get().load(avatarPath)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(target);
} else {
Picasso.get().load(R.drawable.image_thumb).into(target);
}
return this;
}
我从 RecyclerView bindView holder class 中的 Singleton ImageUtils class 调用 loadFromDisk。
PS: bindViewHolder代码
public void onBindViewHolder(@NonNull RecentChatsViewHolder recentChatsViewHolder, int i) {
Log.d(TAG, "onBindViewHolder: content row");
if (recentChat.isNew) {
recentChatsViewHolder.blueDot.setVisibility(View.VISIBLE);
} else {
recentChatsViewHolder.blueDot.setVisibility(View.GONE);
}
recentChatsViewHolder.avatar.setImageResource(R.drawable.ic_info_outline_white_48dp);
ImageUtils.getInstance(context).loadFromDisk(recentChat.id, recentChatsViewHolder.avatar); //this calls above function here I don't pass the else condition of above method so there's no race condition
}
由于这是在 recyclerView 中,我假设发生了某种竞争条件。当您调用 FileDownloader
下载一些图像时。它下载图像并将其加载到目标。但目标不正确,因为回收站视图现在已滚动。
也许,您可以通过将 id
作为标签添加到 ImageView
并在下载图像后检查标签来避免这种情况。如果标签不同,请不要将图像加载到视图中。 -> 这仅在下载 callback/lambda 通过 id
.
编辑:
我不知道 fallback
发生了什么。如果您能从您添加的片段中删除它会更好。
我可以提出两点建议。
ImageView.setImageBitmap(null)
或要求 Picasso 在加载新图像之前清除目标。如果头像不存在,请清空目标- 添加
errorDrawable
,如果出现错误,将不会显示上一张图像。