-
Notifications
You must be signed in to change notification settings - Fork 873
[Enhancement] 网络背景图片缓存+异步下载 #6113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,10 +34,10 @@ | |
| import javafx.scene.paint.Paint; | ||
| import javafx.stage.Stage; | ||
| import javafx.util.Duration; | ||
| import org.glavo.url.WebURL; | ||
| import org.jackhuang.hmcl.Metadata; | ||
| import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDnD; | ||
| import org.jackhuang.hmcl.setting.EnumBackgroundImage; | ||
| import org.jackhuang.hmcl.task.CacheFileTask; | ||
| import org.jackhuang.hmcl.task.Schedulers; | ||
| import org.jackhuang.hmcl.task.Task; | ||
| import org.jackhuang.hmcl.ui.Controllers; | ||
|
|
@@ -52,7 +52,9 @@ | |
| import org.jackhuang.hmcl.ui.wizard.Refreshable; | ||
| import org.jackhuang.hmcl.ui.wizard.WizardProvider; | ||
| import org.jackhuang.hmcl.util.MathUtils; | ||
| import org.jackhuang.hmcl.util.io.FileUtils; | ||
| import org.jackhuang.hmcl.util.platform.OperatingSystem; | ||
| import org.jetbrains.annotations.NotNull; | ||
| import org.jetbrains.annotations.Nullable; | ||
|
|
||
| import java.io.IOException; | ||
|
|
@@ -71,6 +73,8 @@ | |
| import static org.jackhuang.hmcl.util.logging.Logger.LOG; | ||
|
|
||
| public class DecoratorController { | ||
| private static final Path remoteBgCachePath = Metadata.HMCL_CURRENT_DIRECTORY.resolve("bg.png"); | ||
|
|
||
| private final Decorator decorator; | ||
| private final Navigator navigator; | ||
|
|
||
|
|
@@ -169,13 +173,15 @@ public Decorator getDecorator() { | |
| @SuppressWarnings("FieldCanBeLocal") // Strong reference | ||
| private final InvalidationListener changeBackgroundListener; | ||
|
|
||
| private volatile boolean remoteFetched = false; | ||
|
|
||
| private void updateBackground() { | ||
| final int currentCount = ++this.changeBackgroundCount; | ||
| Task.supplyAsync(Schedulers.io(), this::getBackground) | ||
| .setName("Update background") | ||
| .whenComplete(Schedulers.javafx(), (background, exception) -> { | ||
| if (exception == null) { | ||
| if (this.changeBackgroundCount == currentCount) | ||
| if (this.changeBackgroundCount == currentCount && !remoteFetched) | ||
| decorator.setContentBackground(background); | ||
| } else { | ||
| LOG.warning("Failed to update background", exception); | ||
|
|
@@ -184,6 +190,7 @@ private void updateBackground() { | |
| } | ||
|
|
||
| private Background getBackground() { | ||
| remoteFetched = false; | ||
| EnumBackgroundImage imageType = config().getBackgroundImageType(); | ||
| if (imageType == null) | ||
| imageType = EnumBackgroundImage.DEFAULT; | ||
|
|
@@ -206,7 +213,8 @@ private Background getBackground() { | |
| String backgroundImageUrl = config().getBackgroundImageUrl(); | ||
| if (backgroundImageUrl != null) { | ||
| try { | ||
| image = FXUtils.loadImage(WebURL.parseBrowserInput(backgroundImageUrl)); | ||
| asyncFetchRemoteImage(backgroundImageUrl); | ||
| image = tryLoadImage(remoteBgCachePath); | ||
| } catch (Exception e) { | ||
| LOG.warning("Couldn't load background image", e); | ||
| } | ||
|
|
@@ -338,6 +346,26 @@ private Image loadDefaultBackgroundImage() { | |
| } | ||
| } | ||
|
|
||
| private void asyncFetchRemoteImage(@NotNull String backgroundImageUrl) { | ||
| final int currentCount = this.changeBackgroundCount; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 此处存在多线程数据竞争(Data Race)。 这可能导致 建议:
|
||
| new CacheFileTask(backgroundImageUrl) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 请不要使用 |
||
| .setExecutor(Schedulers.io()) | ||
| .thenApplyAsync(Schedulers.io(), path -> { | ||
| if (this.changeBackgroundCount == currentCount) FileUtils.copyFile(path, remoteBgCachePath); | ||
| return FXUtils.loadImage(path); | ||
| }) | ||
| .whenComplete(Schedulers.javafx(), ((image, exception) -> { | ||
| if (exception == null) { | ||
| if (this.changeBackgroundCount == currentCount) { | ||
| decorator.setContentBackground(createBackgroundWithOpacity(image, config().getBackgroundImageOpacity())); | ||
| remoteFetched = true; | ||
| } | ||
| } else { | ||
| LOG.warning("Failed to load network background image from " + backgroundImageUrl, exception); | ||
| } | ||
| })).start(); | ||
| } | ||
|
|
||
| // ==== Navigation ==== | ||
|
|
||
| public void navigate(Node node, AnimationProducer animationProducer, Duration duration, Interpolator interpolator) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remoteBgCachePath被硬编码为程序根目录下的bg.png。这存在以下问题:backgroundImageUrl关联,当用户更改背景图 URL 时,getBackground(第 217 行) 会直接加载并显示旧 URL 的缓存图片,直到新图片下载完成。这会导致界面短暂显示错误的背景图。cache子目录)中,并根据 URL 生成唯一的文件名(例如使用 URL 的哈希值)。.png后缀可能与实际下载的图片格式(如 JPG, WebP, SVG)不符。虽然 JavaFX 能够识别流内容,但错误的后缀可能在某些环境下引起问题。