用于JavaFX的Strange Gluon项目结构 – Android移植

用于将JavaFX移植到Android的Gluon插件(在Netbeans 8.0.2中)的gradle构建创建了以下目录结构:

  1. 源包[Java]
  2. Android / Java包
  3. 桌面/ Java包
  4. Ios / Java包

这些目录中的每一个都包含其中的java包。 通常,Gluon构建将在“源包”目录中的一个java包中为我们创建“主”类[名称包含“源包”的名称可能会产生误导,因为它不是Java包,它只是一个文件系统目录]。 这个主类扩展了Javafx Application类,因此是我们应用程序的入口点。

对于在其中创建的任何Java包,只能在Android / Java Packages目录中访问Android API。 比方说,android.Vibrator类只能在这里引用。

问题是,我们不能将在Android / Java目录内的任何Java包内创建的类引用到Source Packages [Java]目录中创建的任何java包! 如果是这种情况那么我们如何将应用程序从javafx.Application的start()方法转发到android.Vibrator中。

胶子项目结构有一个快照: 如何在Gluon项目中引用android.jar

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

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

正如您所提到的,默认情况下,从主程序包中您将看不到平台程序包中添加的代码,因此您必须提供一种方法。

如果检查JavaFXPorts存储库上的HelloPlatform 示例 ,您将找到一个PlatformService类来使用ServiceLoader加载包。

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

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

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

源包[Java]

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

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

Android / 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下找到它。

现在你可以部署项目并在桌面上运行它( gradlew run )它将工作,并将其安装在Android( gradlew androidInstall )上,它也将工作。