Reputation: 1153
I wanted to ask, if someone ever also had a problem using the Gluon Charm Down plugin for screen orientation for IOS?
JFXMobile Plugin: org.javafxports:jfxmobile-plugin:1.3.2
Charm Version: com.gluonhq:charm:4.2.0
downConfig {
version = '3.1.0'
plugins 'display', 'lifecycle', 'statusbar', 'storage', 'orientation'
}
When I try to call it, like this:
Services.get(OrientationService.class).ifPresent(service -> {
onOrientationChange(service.orientationProperty(), null, service.getOrientation().orElse(Orientation.VERTICAL));
service.orientationProperty().addListener(this::onOrientationChange);
});
I get an exception on the console:
Exception in Preloader start method
2017-02-06 10:43:37.104693 MyApp[447:282589] Orientation is Unknown
QuantumRenderer: shutdown
java.lang.RuntimeException: Exception in Preloader start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$156(LauncherImpl.java)
at com.sun.javafx.application.LauncherImpl$$Lambda$2.run(Unknown Source)
at java.lang.Thread.run(Thread.java)
Caused by: java.lang.NullPointerException
at com.gluonhq.charm.down.plugins.ios.IOSOrientationService.getOrientation(IOSOrientationService.java)
at my.app.Preloader.lambda$start$24(Preloader.java)
at my.app.Preloader$$Lambda$3.accept(Unknown Source)
at java.util.Optional.ifPresent(Optional.java)
at my.app.Preloader.start(Preloader.java)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java)
at com.sun.javafx.application.LauncherImpl$$Lambda$7.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java)
at com.sun.javafx.application.PlatformImpl$$Lambda$7.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java)
at com.sun.javafx.application.PlatformImpl$$Lambda$19.run(Unknown Source)
at java.security.AccessController.doPrivileged(AccessController.java)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java)
at com.sun.javafx.application.PlatformImpl$$Lambda$6.run(Unknown Source)
at org.robovm.apple.uikit.UIApplication.main(UIApplication.java)
at org.robovm.apple.uikit.UIApplication.main(UIApplication.java)
at org.javafxports.jfxmobile.ios.BasicLauncher.main(BasicLauncher.java)
Looking at the code, I assume there could be only one reason for the issue:
@Override
public final Optional<Orientation> getOrientation() {
switch (orientationText) {
case "Portrait":
case "PortraitUpsideDown":
return Optional.of(Orientation.VERTICAL);
case "LandscapeLeft":
case "LandscapeRight":
return Optional.of(Orientation.HORIZONTAL);
case "Unknown":
default:
return Optional.empty();
}
}
My guess is, that orientationText
is null
and therefore it crashes.
The line 2017-02-06 10:43:37.104693 MyApp[447:282589] Orientation is Unknown
contributes to that, I guess.
Is this a bug? Is there some way to circumvent this? (E.g. is there some set-up needed on IOS, like the permission system on Android?)
Thanks in advance and regards,
Daniel
#edit: The onOrientationChange
method is not very complicated:
private void onOrientationChange(ObservableValue<? extends Orientation> obs, Orientation o, Orientation n) {
if (n == null || splashPane == null)
return;
splashPane.pseudoClassStateChanged(vertical, Orientation.VERTICAL == n);
splashPane.pseudoClassStateChanged(horizontal, Orientation.HORIZONTAL == n);
}
So I guess it would be sufficient to update the code to sth. like this
Services.get(OrientationService.class).ifPresent(service -> {
service.orientationProperty().addListener(this::onOrientationChange); });
(it's working on Android, so I could alternatively check the platform and only do it on non-IOS or so)
Upvotes: 1
Views: 157
Reputation: 45476
I can reproduce your NPE.
The error happens when you 'eagerly' call service.getOrientation()
.
If you have a look at the code, orientationText
is not initialized, and it is only when the service is initialized and the observer starts that the value is retrieved from the iOS native layer and set with Platform::runLater
.
This means that it takes a short while to get an initial value for orientationText
.
The quick solution to avoid the NPE is using a regular ChangeListener<Observation>
instead of your onOrientationChange
method:
private final ChangeListener<Orientation> onOrientationChange =
(ObservableValue<? extends Orientation> obs, Orientation ov, Orientation nv) -> {
if (nv == null || splashPane == null)
return;
splashPane.pseudoClassStateChanged(vertical, Orientation.VERTICAL == nv);
splashPane.pseudoClassStateChanged(horizontal, Orientation.HORIZONTAL == nv);
}
Services.get(OrientationService.class).ifPresent(service -> {
service.orientationProperty().addListener(onOrientationChange);
});
Anyway, I'll file an issue to add an initial value to orientationText
.
Upvotes: 1