前言
由于工作原因教届,接觸一些 JavaFX 開發(fā)响鹃。最近產(chǎn)品的同學(xué)提到一個(gè)遺留已久的問題——在網(wǎng)站啟動(dòng)我們的 JavaFX 本地應(yīng)用程序。于是就著手了解一下案训。曾經(jīng)做過 Android 應(yīng)用程序的 web 喚起功能买置。大致就是注冊(cè)一個(gè)自定義的 Scheme,在 web 中嵌入這個(gè)自定義 Scheme 的 URL 喚起本地應(yīng)用强霎,就像 http://
或 https://
的 URL 可以喚起瀏覽器忿项。桌面應(yīng)用也可以通過同樣的方式來啟動(dòng)。下面簡(jiǎn)單的記錄一下實(shí)現(xiàn)過程。
以下文章中的代碼可以在此免費(fèi)下載:javafx-custom-url-scheme轩触。項(xiàng)目使用 maven 管理寞酿,使用 javafx-maven-plugin 插件打包 native 程序。結(jié)構(gòu)如下:
├── README.md
├── javafx-custom-url-scheme.iml
├── pom.xml
└── src
└── main
├── deploy
│ └── package
│ ├── macosx
│ └── windows
├── java
│ └── org
│ └── eirture
│ └── javafx
│ └── App.java
└── resources
通過 URL 喚起 JavaFX Windows 應(yīng)用
通過這篇文檔 Registering an Application to a URI Scheme怕膛,我們知道通過自定義 URI Scheme 喚起本地應(yīng)用熟嫩,需要添加如下注冊(cè)表信息:
HKEY_CLASSES_ROOT
myapp # 自定義協(xié)議的名稱
(Default) = "URL:myapp"
URL Protocol = ""
DefaultIcon # 定義圖標(biāo)
(Default) = "javafx-custom-url-scheme.exe,1" # 圖標(biāo)路徑,‘path,iconIndex’形式
shell
open
command
(Default) = "C:\Program Files\javafx-custom-url-scheme.exe" "%1" # 定義應(yīng)用程序路徑地址褐捻, %1 表示接收一個(gè)參數(shù)掸茅。
下一步我們需要考慮在 JavaFX 程序中將此信息寫入注冊(cè)表。使用 javapackager 打包柠逞,我們會(huì)發(fā)現(xiàn)昧狮,windows 平臺(tái)的 .exe 程序使用的是 InnoSetup
,打包過程輸出的信息提示我們板壮,可以通過
project/deploy/package/windows/AppName.iss
文件自定義打包的配置信息逗鸣,在 InnoSetup 幫助文檔中不難找到添加注冊(cè)表信息的方法。
第一個(gè)問題绰精,我們從哪里獲取 AppName.iss
配置文件呢撒璧。通過打包過程輸出信息,我們發(fā)現(xiàn)笨使,在 ~/AppData/Local/Temp/fxbundler*
目錄下有我們要找的文件卿樱。不過這里面是根據(jù)我們配置的 javafxpackage 打包信息生成的配置文件,如果直接 Copy 過來硫椰,那么這些打包信息就不能根據(jù)我們的配置生成了繁调。其實(shí)我們找到這個(gè)生成配置信息的模版文件放在此處即可: template.iss。將 template.iss 放置 javafx-custom-url-scheme/src/main/deploy/package/windows/MyApp.iss
靶草,增加配置信息如下:
[Registry]
Root: HKCR; Subkey: "myapp"; Flags: uninsdeletekey; ValueType: string; ValueData: "URL:myapp"
Root: HKCR; Subkey: "myapp"; Flags: uninsdeletekey; ValueType: string; ValueName: "URL Protocol"; ValueData: "";
Root: HKCR; Subkey: "myapp\DefaultIcon"; Flags: uninsdeletekey; ValueType: expandsz; ValueData: "APPLICATION_NAME.exe,1"
Root: HKCR; Subkey: "myapp\shell\open\command"; Flags: uninsdeletekey; ValueType: expandsz; ValueData: "{app}\APPLICATION_NAME.exe %1";
開始打包 native 應(yīng)用程序(需要先確保已經(jīng)安裝了 innoSetup)
mvn clean jfx:native
在項(xiàng)目的 target\jfx\native\
目錄下將會(huì)生成我們的應(yīng)用程序 MyApp.exe
蹄胰,安裝后會(huì)自動(dòng)在注冊(cè)表中寫入自定義的 scheme 信息。如下圖所示:
現(xiàn)在就可以在瀏覽器輸入 myapp://
啟動(dòng) MyApp.exe
應(yīng)用程序了奕翔。
通過 URL 喚起 JavaFX Mac OS 應(yīng)用
MacOS 應(yīng)用程序如何自定義 URL Scheme 的教程很多裕寨,在此我們也不過多介紹。需要在應(yīng)用的 Info.plist
文件中添加如下配置:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>org.eirture.javafx.App</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
我們需要解決的問題是派继,使用 javafxpackager 打包 JavaFX 應(yīng)用程序時(shí)帮坚,如何在 Info.plist 文件中添加這些信息。在執(zhí)行 mvn jfx:native
命令打包過程中互艾,可以看到控制臺(tái)輸出了如下信息:
...
Building DMG package for MyApp
正在準(zhǔn)備 Info.plist: /var/folders/vy/hfcccjpx0xz3q53dvj32llmm0000gn/T/fxbundler8587227884586677537/macosx/Info.plist
Using default package resource [包配置文件] (add package/macosx/Info.plist to the class path to customize)
Using default package resource [icon] (add package/macosx/MyApp.icns to the class path to customize)
Running [security, find-certificate, -c, Developer ID Application: , -a]
...
告訴我們將自定義的 Info.plist 文件放至 package/macosx/Info.plist
可以實(shí)現(xiàn)自定義。同 windows 下讯泣,我們需要放入模版文件纫普,并在模版文件中加入我們自定義的配置信息。在 openjfx 項(xiàng)目中可以找到 Info-lite.plist.template 文件,并在文件中加入我們自定義的配置昨稼。
<?xml version="1.0" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSMinimumSystemVersion</key>
<string>10.7.4</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleExecutable</key>
<string>DEPLOY_LAUNCHER_NAME</string>
<key>CFBundleIconFile</key>
<string>DEPLOY_ICON_FILE</string>
<key>CFBundleIdentifier</key>
<string>DEPLOY_BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>DEPLOY_BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>DEPLOY_BUNDLE_SHORT_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<!-- See http://developer.apple.com/library/mac/#releasenotes/General/SubmittingToMacAppStore/_index.html
for list of AppStore categories -->
<key>LSApplicationCategoryType</key>
<string>DEPLOY_BUNDLE_CATEGORY</string>
<key>CFBundleVersion</key>
<string>DEPLOY_BUNDLE_CFBUNDLE_VERSION</string>
<key>NSHumanReadableCopyright</key>
<string>DEPLOY_BUNDLE_COPYRIGHT</string>
<key>JVMRuntime</key>
<string>DEPLOY_JAVA_RUNTIME_NAME</string>
<key>JVMMainClassName</key>
<string>DEPLOY_LAUNCHER_CLASS</string>
<key>JVMAppClasspath</key>
<string>DEPLOY_APP_CLASSPATH</string>
<key>JVMMainJarName</key>
<string>DEPLOY_MAIN_JAR_NAME</string>
<key>JVMPreferencesID</key>
<string>DEPLOY_PREFERENCES_ID</string>
<key>JVMOptions</key>
<array>
DEPLOY_JVM_OPTIONS
</array>
<key>JVMUserOptions</key>
<dict>
DEPLOY_JVM_USER_OPTIONS
</dict>
<key>ArgOptions</key>
<array>
DEPLOY_ARGUMENTS
</array>DEPLOY_FILE_ASSOCIATIONS
<key>NSHighResolutionCapable</key>
<string>true</string>
<!-- custom configuration -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>org.eirture.javafx.App</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
</dict>
</plist>
重新打包安裝节视,即可在瀏覽器通過 myapp://
喚起我們應(yīng)用程序了。
總結(jié)
終于我們實(shí)現(xiàn)了從 web 頁面喚起 JavaFX 本地應(yīng)用程序功能假栓。各個(gè)平臺(tái)上實(shí)現(xiàn)自定義的 URL Scheme 的教程都很多寻行,在此主要是想分享使用 JavaFX 開發(fā),如何配置此功能匾荆。當(dāng)然拌蜘,這里僅僅是通過自定義的 URL Scheme 喚起本地應(yīng)用程序。我們還可以使用自定義的 URLSchemeHandler 接收來自 URL Scheme 的參數(shù)牙丽,例如通過 myapp://user/eirture
給本地應(yīng)用傳遞 user/eirture
信息等简卧。