尝试使用LibGDX游戏引擎中的Gdx.net.openURI(String)
时遇到了一个非常奇怪的问题。这是一种只需在浏览器中打开页面的方法。如果有效,则返回true,否则无效,否则返回false。 它有效(打开页面)并返回true,但是在我的控制台中显示了一个随机异常,并且未捕获到该异常。
boolean opened;
try
{
opened = Gdx.net.openURI(DONATE_URL); //at net.jumpai.client.menu.DonateDialog.<init>(DonateDialog.java:30)
}
catch(Exception ex)
{
opened = false;
}
// some other code that is always executed
这是我得到的输出:
java.io.IOException: Cannot run program "sensible-browser": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:620)
at java.lang.Runtime.exec(Runtime.java:485)
at org.lwjgl.LWJGLUtil$1.run(LWJGLUtil.java:406)
at org.lwjgl.LWJGLUtil$1.run(LWJGLUtil.java:404)
at java.security.AccessController.doPrivileged(Native Method)
at org.lwjgl.LWJGLUtil.execPrivileged(LWJGLUtil.java:404)
at org.lwjgl.LinuxSysImplementation.openURL(LinuxSysImplementation.java:78)
at org.lwjgl.Sys.openURL(Sys.java:257)
at com.badlogic.gdx.backends.lwjgl.LwjglNet.openURI(LwjglNet.java:66)
at net.jumpai.client.menu.DonateDialog.<init>(DonateDialog.java:30)
at net.jumpai.client.world.online.OnlineWorldScreen.donateClicked(OnlineWorldScreen.java:434)
at net.jumpai.util.event.ListenableImpl.trigger(ListenableImpl.java:25)
at net.jumpai.client.menu.AccountMenu.lambda$new$0(AccountMenu.java:54)
at net.jumpai.util.ui.listener.ClickAdapter.lambda$new$0(ClickAdapter.java:43)
at net.jumpai.util.ui.listener.ClickAdapter.clicked(ClickAdapter.java:50)
at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:89)
at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:59)
at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:351)
at com.badlogic.gdx.InputMultiplexer.touchUp(InputMultiplexer.java:96)
at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:332)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:217)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:126)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 22 more
我确保此代码不会执行两次,此问题不是一次正常工作而另一次不正常的情况。这让我印象深刻。这是真正的典范吗?我不知道该怎么抓和打印它。如何防止它发生?
我正在使用ArchLinux,浏览器是Chromium。
答案 0 :(得分:1)
如命令中的Perry Monschau所述,该异常由try
调用的内部方法的catch
-Gdx.net.openURI()
打印。
因此,我制定了一种避免在控制台中发生意外错误的方法:
public static boolean openURI(String uri)
{
PrintStream prevErr = System.err;
try
{
System.setErr(NullPrintStream.instance);
}
catch(SecurityException ignored)
{
return Gdx.net.openURI(uri);
}
try
{
return Gdx.net.openURI(uri);
}
finally
{
System.setErr(prevErr);
}
}
无需先询问即可在控制台中打印内容的方法是LWJGL的LinuxSysImplementation(注释不是我的):
// Linux may as well resort to pure Java hackery, as there's no Linux native way of doing it
// right anyway.
String[] browsers = {"sensible-browser", "xdg-open", "google-chrome", "chromium", "firefox", "iceweasel", "mozilla", "opera", "konqueror", "nautilus", "galeon", "netscape"};
for ( final String browser : browsers ) {
try {
LWJGLUtil.execPrivileged(new String[] { browser, url });
return true;
} catch (Exception e) {
// Ignore
e.printStackTrace(System.err);
}
}
答案 1 :(得分:0)
这些异常是在并行线程中引发的,因此无法在您的主线程中捕获它们。打印到控制台是Java中处理异常的默认行为。尝试使用Thread.setUncaughtExceptionHandler()
方法,它可以帮助您定义更具体的行为来处理情况。