Skip to content

[Enhancement] 网络背景图片缓存+异步下载#6113

Open
ToobLac wants to merge 1 commit into
HMCL-dev:mainfrom
ToobLac:bg-cache
Open

[Enhancement] 网络背景图片缓存+异步下载#6113
ToobLac wants to merge 1 commit into
HMCL-dev:mainfrom
ToobLac:bg-cache

Conversation

@ToobLac
Copy link
Copy Markdown
Contributor

@ToobLac ToobLac commented May 17, 2026

Closes #6079

@ToobLac ToobLac marked this pull request as ready for review May 17, 2026 05:18
@ToobLac ToobLac changed the title [Enhancement] 网络背景图片阻塞启动 [Enhancement] 网络背景图片缓存+异步下载 May 18, 2026
@Glavo
Copy link
Copy Markdown
Member

Glavo commented May 18, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the background image loading mechanism to be asynchronous and includes a local caching strategy. It removes the synchronous WebURL-based image loading from FXUtils and introduces asyncFetchRemoteImage in DecoratorController to handle remote backgrounds. The review feedback identifies a potential data race on the changeBackgroundCount variable when accessed across different threads and highlights issues with the hardcoded cache path bg.png, which could lead to displaying stale images and file format inconsistencies.

import static org.jackhuang.hmcl.util.logging.Logger.LOG;

public class DecoratorController {
private static final Path remoteBgCachePath = Metadata.HMCL_CURRENT_DIRECTORY.resolve("bg.png");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

remoteBgCachePath 被硬编码为程序根目录下的 bg.png。这存在以下问题:

  1. 缓存逻辑错误:由于缓存文件名固定且未与 backgroundImageUrl 关联,当用户更改背景图 URL 时,getBackground (第 217 行) 会直接加载并显示旧 URL 的缓存图片,直到新图片下载完成。这会导致界面短暂显示错误的背景图。
  2. 文件规范:建议将缓存文件存放在专门的缓存目录(如 cache 子目录)中,并根据 URL 生成唯一的文件名(例如使用 URL 的哈希值)。
  3. 格式兼容性:硬编码 .png 后缀可能与实际下载的图片格式(如 JPG, WebP, SVG)不符。虽然 JavaFX 能够识别流内容,但错误的后缀可能在某些环境下引起问题。

}

private void asyncFetchRemoteImage(@NotNull String backgroundImageUrl) {
final int currentCount = this.changeBackgroundCount;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

此处存在多线程数据竞争(Data Race)。changeBackgroundCount 是一个普通的 int 字段,它在 JavaFX 线程中被 updateBackground 修改,但在此处(IO 线程)被读取。同样的问题也存在于第 354 行的异步回调中。

这可能导致 currentCount 获取到过期的值,从而在快速切换背景时导致逻辑错误(例如将旧请求的图片错误地应用或保存到缓存中)。

建议

  1. changeBackgroundCount 声明为 AtomicInteger
  2. 或者将 currentCount 作为参数从 updateBackground 传递给 getBackgroundasyncFetchRemoteImage,确保每个异步任务都持有其启动时的快照值。


private void asyncFetchRemoteImage(@NotNull String backgroundImageUrl) {
final int currentCount = this.changeBackgroundCount;
new CacheFileTask(backgroundImageUrl)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

请不要使用 CacheFileTaskCacheFileTask 会在设备上全局共享一些游戏相关的内容,而背景图更适合在局部进行缓存。把它缓存到全局文件夹的话,如果用户使用类似 Bing 壁纸这样的随机图片链接,那么可能会导致无用缓存越来越多。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 当 设置 - 外观 - 背景图片 设置为 [网络] 时 启动HMCL时间过长

2 participants