import org.openqa.selenium.*;
import org.openqa.selenium.chrome.*;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class AutoWebDriverExit {
private static WebDriver driver;
private static final ExecutorService monitorExecutor = Executors.newSingleThreadExecutor();
private static final AtomicBoolean active = new AtomicBoolean(true);
public static void main(String[] args) {
// 1. Chrome 配置
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-gpu", "--no-sandbox", "--disable-dev-shm-usage");
options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});
// 2. 启动 WebDriver
System.setProperty("webdriver.chrome.driver", "C:/path/to/chromedriver.exe");
driver = new ChromeDriver(options);
// 3. 启动浏览器关闭监听器
startBrowserCloseMonitor();
// 4. 注册 JVM 关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread(() -> safeQuitDriver()));
try {
// 5. 业务代码
driver.get("https://example.com");
// ... 页面操作代码 ...
// 6. 等待浏览器关闭(示例等待)
while (active.get()) {
TimeUnit.SECONDS.sleep(1);
}
System.out.println("浏览器已被关闭,WebDriver 已退出");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void startBrowserCloseMonitor() {
monitorExecutor.submit(() -> {
try {
// 检测浏览器是否关闭
new WebDriverWait(driver, Duration.ofMillis(500))
.until(d -> {
try {
driver.getTitle(); // 尝试执行简单操作
return false; // 浏览器仍在运行
} catch (WebDriverException e) {
handleBrowserClosed(e);
return true; // 浏览器已关闭
}
});
} catch (TimeoutException e) {
// 浏览器仍在运行,继续监控
}
});
}
private static void handleBrowserClosed(WebDriverException e) {
// 1. 设置活动状态为 false
active.set(false);
// 2. 安全退出 WebDriver
safeQuitDriver();
// 3. 记录浏览器关闭信息
System.out.println("检测到浏览器关闭: " + e.getMessage());
System.out.println("WebDriver 资源已成功释放");
}
private static void safeQuitDriver() {
try {
if (driver != null) {
// 避免出现 "Session not created" 异常
try {
driver.close(); // 尝试正常关闭
} catch (Exception ignore) {}
driver.quit(); // 重要:释放 WebDriver 资源
driver = null;
// 关闭监控线程池
monitorExecutor.shutdownNow();
}
} catch (Exception e) {
System.err.println("WebDriver 退出时出错: " + e.getMessage());
}
}
}
当需要自动恢复而不是退出时,可以使用以下扩展方案:
public class AutoRecoveryDriver extends EventFiringWebDriver {
private static final int MAX_RETRIES = 3;
private int retryCount = 0;
public AutoRecoveryDriver(WebDriver driver) {
super(driver);
}
@Override
public void quit() {
try {
super.quit();
} catch (WebDriverException e) {
handleRecovery(e);
}
}
private void handleRecovery(WebDriverException e) {
if (retryCount >= MAX_RETRIES) {
throw e;
}
System.out.println("检测到浏览器意外关闭,尝试恢复 (尝试次数: " + (retryCount+1) + ")");
// 1. 重新初始化 WebDriver
WebDriver newDriver = initNewDriver();
setWrappedDriver(newDriver);
// 2. 增加重试计数
retryCount++;
// 3. 恢复应用状态(如重新登录等)
recoverApplicationState();
}
private WebDriver initNewDriver() {
ChromeOptions options = new ChromeOptions();
// ... 配置 ...
return new ChromeDriver(options);
}
private void recoverApplicationState() {
// 恢复到之前的页面状态
get("https://example.com/login");
// 重新登录或其他状态恢复
// ...
System.out.println("应用状态已成功恢复");
}
}