在 Windows 和 Mac 的網(wǎng)頁上喚起 JavaFX 應(yīng)用

前言

由于工作原因教届,接觸一些 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 信息。如下圖所示:

windows 注冊(cè)表信息

現(xiàn)在就可以在瀏覽器輸入 myapp:// 啟動(dòng) MyApp.exe 應(yīng)用程序了奕翔。

web 喚起 MyApp.exe

通過 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)用程序了。

Web 喚起 MyApp.app

總結(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 信息等简卧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市烤芦,隨后出現(xiàn)的幾起案子举娩,更是在濱河造成了極大的恐慌,老刑警劉巖构罗,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铜涉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡遂唧,警方通過查閱死者的電腦和手機(jī)芙代,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蠢箩,“玉大人链蕊,你說我怎么就攤上這事∶冢” “怎么了滔韵?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)掌实。 經(jīng)常有香客問我陪蜻,道長(zhǎng),這世上最難降的妖魔是什么贱鼻? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任宴卖,我火速辦了婚禮,結(jié)果婚禮上邻悬,老公的妹妹穿的比我還像新娘症昏。我一直安慰自己,他們只是感情好父丰,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布肝谭。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪攘烛。 梳的紋絲不亂的頭發(fā)上魏滚,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音坟漱,去河邊找鬼鼠次。 笑死,一個(gè)胖子當(dāng)著我的面吹牛芋齿,可吹牛的內(nèi)容都是我干的腥寇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼沟突,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼花颗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惠拭,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤扩劝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后职辅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棒呛,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年域携,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了簇秒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秀鞭,死狀恐怖趋观,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锋边,我是刑警寧澤皱坛,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站豆巨,受9級(jí)特大地震影響剩辟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜往扔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一贩猎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧萍膛,春花似錦吭服、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽麦到。三九已至,卻和暖如春欠肾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拟赊。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工刺桃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吸祟。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓瑟慈,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親屋匕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子葛碧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)过吻,斷路器进泼,智...
    卡卡羅2017閱讀 134,693評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,838評(píng)論 6 342
  • 應(yīng)用間通信 應(yīng)用程式只能間接與設(shè)備上的其他應(yīng)用進(jìn)行通信。您可以使用AirDrop與其他應(yīng)用程序共享文件和數(shù)據(jù)纤虽。您還...
    nicedayCoco閱讀 746評(píng)論 0 1
  • 關(guān)于iOS應(yīng)用程序架構(gòu) 應(yīng)用程序需要與iOS一起工作乳绕,以確保他們提供出色的用戶體驗(yàn)。 除了為您的應(yīng)用程序的設(shè)計(jì)和用...
    nicedayCoco閱讀 1,228評(píng)論 0 1
  • 你只是雇用了我 我不是你的雇傭 ——MAE.LIU
    柳如柳閱讀 219評(píng)論 0 0