使用JavaFX構建部署安卓應用

Java平臺最初的目標是爲嵌入式設備提供一個軟件環境。然而,歷史的怪圈卻讓Java成爲了企業軟件開發的首選語言。過去,Java的客戶端應用所受到的關注比利潤豐厚的服務器端市場要少得多。不過,如今Java平臺已經擁有了強大的客戶端組件——JavaFX,可用於開發桌面、平板電腦、移動和嵌入式系統上的應用程序。本文將爲讀者展現如何在Android設備上部署JavaFX應用程序。任何致力於客戶端開發的軟件平臺都須要有一套建立用戶界面的方法。AWT(抽象窗口工具包)曾經被看做是Java平臺用戶界面的根基。一些更高級的工具包(例如Swing)在必定程度上都是以AWT爲基礎的。自從1995年Java首次發佈,AWT就是Java平臺的一部分,如今看來,其設計原則已經至關陳舊,沒法與當今的硬件和軟件能力相匹配。新的Java客戶端組件,JavaFX,是在充分汲取了Java領域以及其餘UI框架的經驗後,從新設計而成。JavaFX的關鍵原則之一就是要儘量地充分利用硬件(如GPU)資源。實際上,現在的用戶界面所需的工具包必須是高響應而且高性能的。可以讓JavaFX應用運行在iOS和Android平臺上是相當重要的。現在,愈來愈多的應用程序不只須要可以在桌面電腦上運行,也須要可以在移動設備和平板電腦上運行。用三種語言編寫同一應用的三種版本的代價至關昂貴:一個桌面版本,一個iOS版本和一個Android版本。而使用JavaFX,則能夠將同一個應用直接部署到所有三個平臺上。固然,各個平臺都有其各自的UI特性須要遵循,不過JavaFX平臺提供了許多方法以達成這一目標,例如使用CSS和自定義皮膚。JavaFX做爲官方的Java客戶端組件,是Java SE環境重要的組成部分。在所支持的系統上,它是與JDK和JRE綁定在一塊兒的。所以,在Windows,MacOS X,Linux和嵌入式ARM系統上,Oracle將JavaFX做爲Java SE版本的一部分統一發布。對於iOS和Android平臺來講,目前尚無Oracle官方發佈的JavaFX。不過,開發者社區已經彌補了這一缺口。RoboVM團隊正在添加RoboVM對JavaFX的支持,這樣就可使用RoboVM編譯器編譯JavaFX應用程序並在iOS設備上運行它們。稍後在本文中咱們將着重闡述要可以在iOS和Android平臺運行JavaFX應用的另外一個緣由。在此以前,咱們首先爲你們介紹如何在Android平臺上運行已有的JavaFX應用。java

Android上的JavaFX

本文的剩餘部分將介紹如何在Android上部署JavaFX應用程序。關於如何在Android平臺上編譯、打包和部署JavaFX應用程序的詳細說明能夠訪問JavaFX移植團隊的網站。android

一般來講,部署JavaFX應用程序的步驟以下:服務器

一、下載Android SDK和JavaFX-Android SDK微信

二、建立一個JavaFX應用網絡

三、使用JavaFX-Android SDK建立基於上述JavaFX應用的Android項目框架

四、使用Ant構建系統建立Android程序包模塊化

五、將程序包上傳至應用商店工具

第一步:下載Android SDK和JavaFX-Android SDK

在編譯和構建應用程序以前,首先須要安裝Android SDK和JavaFX-Android SDK。Android SDK是由Google提供的軟件開發工具包,能夠從Android開發者支持網站上下載。其中包含了android.jar API和將Java類文件轉換成Dalvik字節碼的工具。Android SDK還提供了可與Android設備通訊的工具,用於日誌檢查和將應用程序傳輸到設備上。下載完成後,能夠很方便地將ANDROID_SDK環境變量指向所下載的adt-bundle-xxx/sdk文件夾(xxx與所下載的版本和對應的操做系統相關。)Dalvik JavaFX-Android SDK(由JavaFX的Android移植團隊提供)能夠從BitBucket網站的JavaFX Ports項目中下載。下載並解壓最新的dalvik-sdk-version.zip文件。(咱們能夠將環境變量DALVIK_SDK設置指向剛剛解壓縮的dalvik-sdk文件夾)。JavaFX-Android SDK中包含一個運行在Android平臺上的JavaFX實現,一些用於構建Android程序包的工具以及一個「Hello,Android」 JavaFX示例程序。能夠在剛剛下載的DALVIK_SDK/samples目錄下找到這個示例程序。除此以外,咱們還須要用於構建apk文件的Ant程序。若是電腦上尚未Ant程序,能夠從Apache Ant網站上下載。佈局

第二步:建立JavaFX應用

在Android平臺建立JavaFX應用與在桌面電腦系統上建立JavaFX應用的步驟徹底一致。咱們能夠選擇慣用的IDE和構建工具來建立JavaFX應用。這樣,建立Android程序包的旅途就順利開始了。在這一步,咱們無須建立特定的JavaFX應用程序啓動器或增長任何配置。JavaFX-Android SDK已經爲咱們提供了相應的工具,咱們將在接下來的步驟裏討論這些工具。雖然一般來講,最好可以保持代碼的平臺獨立性,不過在某些狀況下,例如在沒有相應的JavaFX或Java API可用時,若是可以利用Android平臺特有的實現會更加方便一些。Android平臺提供了許多爲應用提供各類功能的服務(如獲取位置信息)。要使用這些服務,只需添加對android.jar(位於Android SDK中)的依賴並引用其所包含的類便可。不過,須要注意的是,這些Android平臺特有的功能沒法在其餘系統上(如桌面系統)使用。另外,考慮到桌面應用的UI面積比手持設備的更大,在建立Android應用的佈局時,須要可以適用於較小的UI面積。能夠研究一下samples文件夾下的HelloAndroid類,以瞭解如何獲取屏幕的邊界並使用屏幕邊界設置Stage和Scene的邊界。若是想要用示例程序執行上述步驟,使用cd命令切換到以前下載的DALVIK_SDK目錄下的samples/HelloWorld文件夾下。性能

將應用打包成jar文件。打包示例程序,首先須要cd切換到DALVIK_SDK/samples/HelloWorld/javafx目錄下,而後構建應用程序——在Linux和MacOS上使用./gradlew,在Windows上使用gradlew.bat。(咱們不須要下載Gradle,gradlew會爲咱們完成這項工做。)執行這個命令會在javafx/build/libs文件夾下建立一個jar文件(HelloWorld.jar)。除了Gradle以外,咱們也可使用Maven,Ant或者其餘任何工具來構建應用,只要可以生成jar文件便可。

第三步:使用JavaFX-Android SDK生成基於JavaFX應用的Android項目

DALVIK_SDK目錄下的「tools」文件夾中包含一個名爲「convertJavaFXToAndroid.sh」的構建腳本,可用於生成Android項目。簡單來講,Android項目就是一個文件夾,其中包含了一些文件和構建腳本,用於生成Android程序包(apk文件)。構建項目以前,咱們須要進行一系列的參數配置,包括Android SDK和JavaFX-Android SDK的位置,JavaFX應用的位置以及包含main類的文件名稱等。咱們只需對DALVIK_SDK/samples/HelloWorld/convertJavaFXToAndroid.sh文件稍做修改,就可以讓它正常運行。在文件頂部,將變量ANDROID_SDK指向以前下載的ANDROID_SDK文件夾。(目前尚未Windows版本的構建腳本convertJavaFXToAndroid.bat,不過咱們能夠拷貝.sh文件,而後稍做修改,就能夠自制一個Windows版本的構建腳本。)關於生成Android項目的更多信息,請參見DALVIK_SDK/samples/HelloWorld/README文件。在調用convertJavaFXToAndroid.sh腳本以前,在這個腳本的同一文件夾下必需要包含build.gradle及其餘gradle相關的文件。將samples目錄下的全部gradle相關的文件和整個gradle目錄拷貝到咱們本身建立的JavaFX項目的根目錄下,並對convertJavaFXToAndroid.sh腳本作出相應的修改。而後調用convertJavaFXToAndroid.sh腳本。咱們就能夠在samples/HelloWorld/javafx/build目錄下找到新生成的Android項目。

在構建項目時,咱們可使用與示例程序的構建腳本相同的模式。相關參數的定義以下:

-PDIR:生成Android項目的文件夾路徑。

-PPACKAGE:Android包名稱。

-PNAME:生成的Android apk文件名。

-PANDROID_SDK:Android SDK。

-PJFX_SDK:Dalvik SDK。

-PJFX_APP:JavaFX應用jar包所在目錄。

-PJFX_MAIN:JavaFX主啓動器的類名。

第四步:使用Ant構建系統建立Android程序包

在上一步驟中生成的Android項目文件夾「build」中包含一個build.xml文件。切換到build文件夾下並運行「ant debug」。這個命令會生成一個能夠安裝到Android設備上的Android「調試程序包」。使用Android SDK中的Android工具能夠將上述.apk文件發送到設備上。如,調用命令

$ANDROID_SDK/platform-tools/adb -r install /path/to/the.apk

若是須要獲取日誌信息,能夠執行以下命令:

$ANDROID_SDK/platform-tools/adb logcat

須要讓JavaFX應用可以運行在iOS和Android平臺的另外一個重要的緣由是經過應用商店(Apple應用商店和Google Play商店)發佈的這種模式。過去,如何將Java應用發佈到各類各樣的移動手機上,是令許多Java客戶端開發人員感到至關有挫敗感的工做之一。儘管有過許多標準化的嘗試(例如,MIDP),不過若是沒有設備製造商、網絡運營商或兩者共同的幫助,想要將J2ME應用部署到大量的設備上還是一件至關困難的事情。如今,在移動設備上建立和安裝應用已經變得十分簡單。iOS和Android平臺都有本身的應用商店,可供開發者上傳應用,終端用戶下載和運行應用。雖然iOS應用商店和Android Play商店都有一系列應用程序須要知足的要求和設計準則,不過在iOS應用商店和Google Play商店都已經存在JavaFX的應用,也就是說基於JavaFX的應用能夠被應用商店所接受。這爲Java客戶端應用開發者創造了巨大的市場。JavaFX的Android應用與任何其餘Android應用沒有什麼兩樣。上傳到Google Play商店的方式是相同的。並且與其餘Android應用相似,在上傳應用以前,須要將許多指導方針考慮在內。這些指導方針不該被視爲使人厭煩的教條,而應被看做是提供給JavaFX開發者的幫助,以保持他們的應用與其餘Android應用的一致性,這會讓終端用戶更容易接受JavaFX應用。

第五步:部署到應用商店(正在進行的工做)

將JavaFX應用上傳到Google Play商店並不是十分困難,不過目前爲止仍有許多步驟須要遵循。從使用慣用的IDE編寫JavaFX應用到將應用提交到Play商店的道路仍然很漫長。並且須要熟悉各類各樣的系統。若是用Maven開發JavaFX應用,就須要用到3種不一樣的構建系統:用於應用開發的Maven,用於建立Android項目的Gradle和用於構建Android程序包的Ant。意圖改善這個問題的一些工做正在進行中。有許多方法可以改變這種情況,其中一些方法已在研究階段。例如, Android最近將Gradle轉爲其首選的構建環境。Android的Gradle插件可讓編譯JavaFX應用變得更加容易,不過目前仍然還有許多問題有待解決。另外,與JDK一同發佈的JavaFXPackager主要用於爲不一樣的目標環境提供相應的程序包。若是這一工具可以集成在JavaFX-Android SDK中將會更好。此外,一些IDE(NetBeans、Eclipse和IntelliJ IDEA)已經包含了一些用於Android開發的插件。若是可以在這些IDE中集成對JavaFX的支持,熟悉這些IDE的開發人員的工做將會變得更加輕鬆高效。JavaFX的Android移植團隊選擇先爲開發者提供一個端到端工具集,以幫助他們將應用上傳到Play商店中。這說明已經沒有技術或法律問題阻礙咱們編寫Android上的JavaFX應用。接下來,端到端部署的各個部分也將會不斷完善。

底層實現揭祕

JavaFX平臺是在OpenJDK的子項目——OpenJFX中開發的,OpenJDK一般被視爲Java平臺開發的大本營。全部的代碼開發和話題討論都是基於一個開放的環境的。OpenJFX代碼庫中包含了多個平臺上的JavaFX API和實現。JavaFX自己的體系結構是模塊化的,平臺相關的部分與通用的部分是相互獨立的。考慮到JavaFX其中一項設計原則就是要儘量的利用硬件加速,可以實現這樣的設計至關不易。JavaFX-Android SDK是基於OpenJFX代碼庫中的代碼所建立。移植過程當中有兩個主要的挑戰:

OpenJFX代碼中包含一些原生代碼,須要交叉編譯這些代碼以適用於Android系統。

Android上的Dalvik運行環境只包含Java 7的一個子集。不過對拉姆達表達式的支持已經包含在其中。

第一個挑戰已經在OpenJFX中完全解決。實現Android平臺上的JavaFX原生功能所需的全部代碼已經包含在OpenJFX中。第二個挑戰之因此可以解決的主要緣由是OpenJFX的開發者們已經達成共識,不在JavaFX 8u20這一版本中使用Java 8特有的功能。不過,還有許多對Java 7的API調用仍然沒法在Android平臺上正常運行。好消息是JavaFX-Android SDK自己已經包含了這些缺失的API實現。RetroLambda 項目(已經包含在發佈包中)可以替換類文件中動態調用的字節碼,所以咱們能夠在Android平臺上的JavaFX應用中使用拉姆達表達式。另外,須要注意的是,目前還不支持java.util.Streams。

Android概念的映射

Android應用的生命週期與典型的桌面應用的生命週期有必定區別。Android使用了Activity的概念。Android與JavaFX之間的概念轉換做爲其中一部分工做,由JavaFX-Android SDK統一完成。JavaFX-Android SDK包含了一個名爲FXActivity的Activity的子類,在JavaFX應用啓動時,這個類將被實例化。整個JavaFX應用都是這個Activity的一部分。在JavaFX應用啓動時,JavaFX將接管一切。這樣作的好處是讓JavaFX的生命週期事件和應用的組織結構,包括導航,可以像桌面應用同樣。在進行生命週期管理時,不須要了解Android平臺相關的知識。通常狀況下,開發者但願應用是設備無關的,不過在不少時候,也但願可以充分利用Android的特性。針對這些狀況,JavaFX-Android SDK爲JavaFX開發者提供了一些用於訪問Android API的鉤子。第一個鉤子就是由JavaFX-Android SDK生成的Android的清單文件。默認的清單文件適用於比較簡單的應用,不過開發者也能夠對其進行配置。在這個文件中將完成權限請求和基礎的Android配置參數的設置工做。另外,Android平臺還爲JavaFX平臺提供了許多與Android設備關聯更加緊密的服務,例如位置服務、與NFC閱讀器通訊的服務等。在標準的Android應用中,能夠經過Android的Activity和Context類訪問這些服務。在JavaFX平臺中並不存在這些Android特有的類。不過JavaFX-Android SDK提供了一個靜態方法

Context context = FXActivity.getInstance();

用來訪問與建立和運行JavaFX應用的Activity相關聯的Context實例。這個靜態方法所返回的Context實例可用於獲取Android特有的服務。關於如何使用NFC閱讀器的示例能夠參考這裏。在開源項目OpenMapFX中能夠找到另一個相似的關於如何使用GPS服務的示例。若有更多關於JavaFX在Android平臺上的問題,從Google小組中的JavaFX Android論壇裏能夠獲取到更多有用的信息。

更多幹貨筆記關注微信公衆號 : 老九學堂

相關文章
相關標籤/搜索