【问题标题】:Null Pointer on reading the screen orientation from Gluon Charm Down从 Gluon Charm Down 读取屏幕方向的空指针
【发布时间】:2017-02-07 17:14:37
【问题描述】:

我想问一下,是否有人在使用 Gluon Charm Down 插件进行 IOS 屏幕方向时也遇到过问题?

JFXMobile 插件:org.javafxports:jfxmobile-plugin:1.3.2

魅力版:com.gluonhq:charm:4.2.0

downConfig {
        version = '3.1.0'
        plugins 'display', 'lifecycle', 'statusbar', 'storage', 'orientation'
}

当我尝试调用它时,像这样:

Services.get(OrientationService.class).ifPresent(service -> {
    onOrientationChange(service.orientationProperty(), null, service.getOrientation().orElse(Orientation.VERTICAL));
    service.orientationProperty().addListener(this::onOrientationChange);
});

控制台出现异常:

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)

查看code,我认为问题可能只有一个原因:

@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();
    }
}

我的猜测是,orientationTextnull,因此它崩溃了。

我猜2017-02-06 10:43:37.104693 MyApp[447:282589] Orientation is Unknown 行对此有所贡献。

这是一个错误吗?有什么办法可以规避这种情况吗? (比如IOS需要设置一些权限吗,比如安卓的权限系统?)

提前致谢和问候,

丹尼尔


#edit: onOrientationChange 方法不是很复杂:

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);
}

所以我想将代码更新为某事就足够了。像这样

Services.get(OrientationService.class).ifPresent(service -> {

service.orientationProperty().addListener(this::onOrientationChange); });

(它在 Android 上运行,所以我可以选择检查平台,只在非 IOS 上运行)

【问题讨论】:

  • 鉴于日志给出了非空方向,我不认为orientationText 为空。你能修改你的事件处理程序吗?暂时不要使用onOrientationChange。只需打印出方向新值:service.orientationProperty().addListener((obs, ov, nv) -&gt; System.out.println("O: " + nv)); 看看是否失败。
  • 我用onOrientationChange 的内容更新了我的问题(见底部) - 但是,是的,我可以试试。午饭后给你结果好吗?

标签: java ios javafx javafxports gluon-mobile


【解决方案1】:

我可以重现你的 NPE。

当您“急切地”致电service.getOrientation() 时会发生错误。

如果你看一下codeorientationText 没有初始化,只有当服务初始化并且观察者启动时,才会从 iOS 原生层获取值并设置为Platform::runLater .

这意味着获得orientationText 的初始值需要很短的时间。

避免 NPE 的快速解决方案是使用常规 ChangeListener&lt;Observation&gt; 而不是您的 onOrientationChange 方法:

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);
});

无论如何,我会提出一个问题,为orientationText 添加一个初始值。

【讨论】:

  • 对不起,我昨天忘记回答了。无论如何:是的-我已经按照您在评论中的建议进行了操作,并删除了明确的#getOrientation 呼叫,并且仅依赖于侦听器。非常感谢!再次...
  • 没问题,问题已经解决。它在 Charm Down 快照中或在下一个版本之后可用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多