JavaFX WebEngine加载含video标签的Steam页面后崩溃卡顿问题
问题描述
本人是Java新手,正在开发一款基于JavaFX的Steam个人资料背景预览器来提升Java技术。用WebEngine加载带动态背景的Steam个人资料页面后,滚动、悬停等操作都会触发页面重载,导致应用极度卡顿,甚至短时间内崩溃,错误码为-1073741819 (0xC0000005)。尝试移除video源后问题仍存在,请问该如何解决?除javafx-web外是否还需添加视频播放相关依赖?
加载的Steam个人资料链接:https://steamcommunity.com/id/voscope/
代码片段
尝试保留和移除video源两种方式运行应用,问题均存在。移除video源的代码位于注释“Removing header and animated background video sources”下方:
package org.example; import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.scene.web.WebView; import javafx.scene.web.WebEngine; import org.w3c.dom.Document; import javafx.concurrent.Worker; /** * JavaFX App */ public class App extends Application { @Override public void start(Stage stage) { stage.setTitle("Steam Assistant"); stage.setMaximized(true); WebView browser = new WebView(); WebEngine webEngine = browser.getEngine(); webEngine.load("https://steamcommunity.com/id/voscope/"); // Removing header and animated background video sources /*webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> { if (newState == Worker.State.SUCCEEDED) { Document document = webEngine.getDocument(); var header = document.getElementById("global_header"); header.setAttribute("style", "display: none;"); var video = document.getElementsByTagName("video").item(0); video.removeChild(video.getFirstChild()); webEngine.executeScript("document.getElementsByTagName('video')[0].load()"); } });*/ var scene = new Scene(new StackPane(browser), 640, 480); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(); } }
Maven属性
| Property Key | Property Value |
|---|---|
| archetypeGroupId | org.openjfx |
| archetypeArtifactId | javafx-archetype-simple |
| archetypeVersion | 0.0.6 |
| javafx-version | 19 |
pom.xml(已添加最新版19的javafx-web依赖)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>HelloFX</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>19</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-web</artifactId> <version>19</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>11</release> </configuration> </plugin> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.6</version> <executions> <execution> <!-- Default configuration for running --> <!-- Usage: mvn clean javafx:run --> <id>default-cli</id> <configuration> <mainClass>org.example.App</mainClass> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
解决方案
1. 页面重载与崩溃问题修复
错误码0xC0000005是Windows平台的内存访问违规错误,核心原因是JavaFX WebEngine(基于WebKit)与Steam页面的复杂JS脚本、动态DOM操作兼容性冲突,导致内存泄漏或非法内存访问。
具体解决步骤:
- 阻止页面自动重载与不必要的事件触发:在页面加载完成后注入JS,禁用滚动、悬停等事件的默认行为,阻止页面重载逻辑:
webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> { if (newState == Worker.State.SUCCEEDED) { // 取消页面重载监听 webEngine.executeScript("window.onbeforeunload = null;"); // 阻止滚动、悬停触发的动态脚本 webEngine.executeScript("document.addEventListener('scroll', e => e.preventDefault(), true);"); webEngine.executeScript("document.addEventListener('mouseover', e => e.preventDefault(), true);"); // 清除页面定时器,避免重复触发操作 webEngine.executeScript("Object.keys(window).forEach(key => {if(key.includes('interval') || key.includes('timeout')) clearInterval(window[key])})"); } }); - 升级JavaFX版本:JavaFX 19属于旧版本,建议升级到21 LTS版本,该版本对WebKit内核进行了大量更新,修复了不少内存泄漏和兼容性问题。
- 限制WebView资源占用:禁用磁盘和内存缓存,减少内存消耗:
webEngine.getPreferences().setBoolean("webkit.cache.disk.enable", false); webEngine.getPreferences().setBoolean("webkit.cache.memory.enable", false);
2. 视频播放依赖说明
不需要额外添加视频播放依赖,javafx-web模块已集成WebKit的媒体播放组件。若出现视频无法播放的情况,需确认使用的是官方完整的OpenJFX发行版,部分精简版可能缺失媒体解码库。
3. 性能优化替代方案
直接抓取Steam个人资料的背景资源URL,用JavaFX MediaPlayer单独播放,避免加载整个复杂的Steam页面,从根源解决卡顿问题:
webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> { if (newState == Worker.State.SUCCEEDED) { // 提取背景视频URL String bgVideoUrl = (String) webEngine.executeScript("document.querySelector('.profile_background_video source')?.src || '';"); if (!bgVideoUrl.isEmpty()) { // 切换为MediaPlayer播放背景 Media media = new Media(bgVideoUrl); MediaPlayer mediaPlayer = new MediaPlayer(media); MediaView mediaView = new MediaView(mediaPlayer); // 设置媒体视图铺满窗口 mediaView.setFitWidth(stage.getWidth()); mediaView.setFitHeight(stage.getHeight()); mediaView.setPreserveRatio(false); StackPane root = new StackPane(mediaView); stage.setScene(new Scene(root)); mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE); mediaPlayer.play(); } } });
内容的提问来源于stack exchange,提问作者samiayaz
相关产品推荐
相关产品推荐

