3

The gradle build of Gluon plugin (in Netbeans 8.0.2) for porting JavaFX to Android creates the following directory structures:

  1. Source Packages [Java]
  2. Android/Java Packages
  3. Desktop/Java Packages
  4. Ios/Java Packages

Each of these directories contain java packages inside them. Generally Gluon build would create the "main" class for us in one java package inside "Source Packages" directory [the name Packages with "Source Packages" might be misleading since it is not a Java package, its just a file system directory]. This main class extends Javafx Application class and thus is the entry point into our application.

The Android API is accessible only in Android/Java Packages directory for any java package created inside it. Say, the android.Vibrator class is only referr-able here.

The problem is, we cannot refer to a class created inside any Java package inside Android/Java directory to any java package created inside Source Packages [Java] directory!! If this is the case then how would we take the application forward from the start() method of javafx.Application into say android.Vibrator.

The gluon project structure has a snapshot at: How to reference android.jar in Gluon Project

4

1 回答 1

2

如您所知,JavaFXPorts 项目允许在桌面、Android 和 iOS 设备中部署 JavaFX 应用程序。当它只是纯 JavaFX 代码时,该项目被添加到 Main 范围内,并且从那里它将在所有这些平台中可见。

只有在您需要一些特定于平台的代码的情况下,您才应该将其添加到相应的包中。

正如您所提到的,默认情况下,在 Main 包中,您不会在平台包中看到添加的代码,因此您必须为此提供一种方法。

如果您查看 JavaFXPorts 存储库上的 HelloPlatform示例,您会发现一个PlatformService类可以使用ServiceLoader.

另一种可能性是使用Class.forName()在运行时动态加载类,一旦我们知道应用程序正在运行的平台。

我建议你看看Gluon Down项目,它为你管理几个特定于平台的服务,并为你提供统一的、独立于平台的 API。

对于那些在Down中尚不可用的服务(请随意贡献),您可以像在这个使用 Gluon Plugin创建的简单应用程序中那样实现它们。

源包 [Java]

首先,创建一个getPlatform()方法,并将引用的类添加到每个特定平台。例如,添加org.gluonoss.vibrator.GluonAndroidPlatform.javaAndroid 包。

public class GluonPlatformFactory {

    public static GluonPlatform getPlatform() {
        try {
            String platform = System.getProperty("javafx.platform", "desktop");
            String path = "org.gluonoss.vibrator.GluonDesktopPlatform";
            if(platform.equals("android")) {
                path = "org.gluonoss.vibrator.GluonAndroidPlatform";
            } else if(platform.equals("ios")) {
                path = "org.gluonoss.vibrator.GluonIosPlatform";
            }
            return (GluonPlatform) Class.forName(path).newInstance();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            System.out.println("Platform Error "+e.getMessage());
        }
        return null;
    }
}

现在,在所有平台上使用您想要的方法创建一个接口:

public interface GluonPlatform {

    void vibrate();

}

最后,在您的主类上检索平台并调用您的方法:

    @Override
    public void start(Stage stage) {
        final Button button = new Button("Click me!");

        button.setOnAction(e-> GluonPlatformFactory.getPlatform().vibrate());

        StackPane root = new StackPane(button);

        Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
        Scene scene = new Scene(root, visualBounds.getWidth(), visualBounds.getHeight());

        stage.setScene(scene);
        stage.show();
    }

桌面/Java 软件包

添加振动方法。现在将其留空,但您可以添加一个Timeline来移动按钮,例如。

 public class GluonDesktopPlatform implements GluonPlatform {

    @Override
    public void vibrate() {
        System.out.println("Vibrating!");
    }

}

安卓/Java 软件包

添加振动方法。请注意,我们必须使用FXActivity,它是 JavaFX 线程和 Android 活动之间的桥梁。

public class GluonAndroidPlatform implements GluonPlatform {

    @Override
    public void vibrate() {
        Vibrator v = (Vibrator) FXActivity.getInstance().getSystemService(Context.VIBRATOR_SERVICE);
        v.vibrate(500);
    }

}

不要忘记在您的 AndroidManifest 文件中添加所需的权限(您可以在src/android/AndroidManifest.xml.

现在您可以部署该项目并在 Desktop ( gradlew run) 上运行它,它会工作,并在 Android ( ) 上安装它gradlew androidInstall,它也将工作。

于 2015-08-30T12:24:59.350 回答