ComposeDesktop初體驗之打包-創(chuàng)新互聯(lián)

從 0 到 1 搞一個 Compose Desktop 版本的玩天氣之打包

大家好,前兩篇文章大概介紹了下上手Compose Desktop和自定義繪制時遇到的一些問題,項目的最終實現(xiàn)效果如下:

在友誼等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作按需網(wǎng)站策劃,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站制作,友誼網(wǎng)站建設(shè)費用合理。

視頻

代碼寫好了,該弄的動畫也弄了,該請求的網(wǎng)絡(luò)數(shù)據(jù)也請求了,該實現(xiàn)的效果也都實現(xiàn)好了,但是?。。≡蹅兊么虬鰜戆?!不打包出來別人如何使用呢?難道說別人想用你開發(fā)的桌面應(yīng)用,結(jié)果你給他說你先下載一個IntelliJ Idae,然后下載下我的源碼,之后把環(huán)境配置好,最后運行就可以了!如果下次再想用的時候再運行一次就好了!

這說的是人話嘛😂,肯定不能這樣,所以一定要打包!由于Compose Desktop不止可以運行在Mac中,還可以運行在WindowsLinux中,所以需要打多個包。那使用Compose Desktop應(yīng)該如何打包呢?且聽我慢慢道來!

基本用法

插件中的基本配置單元是一個application,application是什么呢?在第一篇文章中也提到了,就是在build.gradle.kts文件中的代碼,咱們再來看下:

compose.desktop {application {mainClass = "MainKt"
        nativeDistributions {targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
            packageName = "Demo"
            packageVersion = "1.0.0"
        }
    }
}

一個application定義了一組最終二進(jìn)制文件的共享配置。換句話說,applicationDSL 允許將一堆文件連同 JDK 分發(fā)包打包成一組各種格式(.dmg、.deb、.msi、.exe等)的壓縮二進(jìn)制安裝程序。

該插件創(chuàng)建以下任務(wù):

  • package(例如packageDmgpackageMsi)用于將應(yīng)用程序打包成相應(yīng)的格式。這塊需要注意的是,目前沒有交叉編譯支持,因此只能使用特定操作系統(tǒng)構(gòu)建格式(例如,要構(gòu)建.dmg就必須使用 macOS)。默認(rèn)情況下會跳過與當(dāng)前操作系統(tǒng)不兼容的任務(wù)。
  • packageDistributionForCurrentOS是一個生命周期任務(wù),聚合了應(yīng)用程序的所有包任務(wù)。
  • packageUberJarForCurrentOS用于創(chuàng)建單個 jar 文件,其中包含當(dāng)前操作系統(tǒng)的所有依賴項。
  • run用于在本地運行應(yīng)用程序。需要定義一個mainClass包含該main函數(shù)的類。請注意,run將啟動具有完整運行時的非打包 JVM 應(yīng)用程序。這比創(chuàng)建具有最小運行時間的緊湊二進(jìn)制映像更快、更容易調(diào)試。要運行最終的二進(jìn)制圖像,需要改用runDistributable。
  • createDistributable用于在不創(chuàng)建安裝程序的情況下創(chuàng)建預(yù)打包的應(yīng)用程序映像和最終應(yīng)用程序映像。
  • runDistributable用于運行預(yù)先打包的應(yīng)用程序映像。
  • 只有在腳本中使用blockproperty時才會創(chuàng)建任務(wù)。

光這么說其實有點懵,來一張圖大家就明白我說的是什么了!

在這里插入圖片描述

是不是有點恍然大明白的感覺!直接點擊IntelliJ IDEA右側(cè)邊欄的Gradle,就會出現(xiàn)這個側(cè)邊欄,然后點擊Task中的compose desktop就會出現(xiàn)上面描述的那些任務(wù)。

打包配置

Compose Desktop打包有很多的配置項,下面來分別看下。

配置包含的 JDK 模塊

Gradle 插件使用 jlink 通過僅包含必要的 JDK 模塊來最小化可分發(fā)的大小。

此時,Gradle 插件不會自動確定必要的 JDK 模塊。未能提供必要的模塊不會導(dǎo)致編譯問題,但會導(dǎo)致在運行時出現(xiàn)ClassNotFoundException的錯誤。

如果在運行打包的應(yīng)用程序或任務(wù)時遇到ClassNotFoundException,可以使用DSL 方法runDistributable來配置包含額外的 JDK 模塊,需要使用modules來配置。

可以通過手動或運行suggestModules任務(wù)來確定哪些模塊是必需的。suggestModules使用 jdeps 靜態(tài)分析工具來確定可能缺少的模塊。

如果安裝包的大小不重要的話,可以使用includeAllModulesDSL 屬性簡單地包括所有運行時模塊作為替代。

compose.desktop {application {nativeDistributions {modules("java.sql")
            // alternatively: includeAllModules = true
        }
    }
}

這塊在我打包的時候搜了好久!最后在Issue中找到了解決方案!

可用格式

以下格式可用于支持的操作系統(tǒng):

  • macOS —.dmg(TargetFormat.Dmg)、.pkg(TargetFormat.Pkg)
  • Windows —.exe(TargetFormat.Exe)、.msi(TargetFormat.Msi)
  • Linux —.deb(TargetFormat.Deb)、.rpm(TargetFormat.Rpm)
指定包版本

由于可以打多種不同的包,也有可能需要區(qū)分不同的版本,所以可以指定包的版本。如何指定的呢?來看代碼:

compose.desktop {application {nativeDistributions {packageVersion = "1.0.0" 
            
            linux {  packageVersion = "1.0.0" 
              debPackageVersion = "1.0.0" 
              rpmPackageVersion = "1.0.0" 
            }
            macOS {  packageVersion = "1.1.0"
              dmgPackageVersion = "1.1.0" 
              pkgPackageVersion = "1.1.0" 
              
              packageBuildVersion = "1.1.0"
              dmgPackageBuildVersion = "1.1.0" 
              pkgPackageBuildVersion = "1.1.0" 
            }
            windows {  packageVersion = "1.2.0"  
              msiPackageVersion = "1.2.0"
              exePackageVersion = "1.2.0" 
            }
        }
    }
}

必須為本機(jī)分發(fā)包指定包版本,還可以使用以下 DSL 屬性(按優(yōu)先級降序排列):

  • nativeDistributions..PackageVersion指定單個包格式的版本;
  • nativeDistributions..packageVersion指定單個目標(biāo)操作系統(tǒng)的版本;
  • nativeDistributions.packageVersion指定所有包的版本;

對于 macOS,還可以使用以下 DSL 屬性指定構(gòu)建版本(按優(yōu)先級降序排列):

  • nativeDistributions.macOS.PackageBuildVersion指定單一包格式的構(gòu)建版本;
  • nativeDistributions.macOS.packageBuildVersion為所有 macOS 包指定構(gòu)建版本。

需要注意的是,版本必須遵循以下規(guī)則:

  • dmgpkg:格式為 MAJOR.MINOR.PATCH

    其中:MAJOR是一個 >0 的整數(shù);MINOR是一個可選的非負(fù)整數(shù);PATCH是一個可選的非負(fù)整數(shù);

  • msiexe:格式為 MAJOR.MINOR.BUILD

    其中:MAJOR是一個非負(fù)整數(shù),大值為255;MINOR是一個非負(fù)整數(shù),大值為255;BUILD是一個非負(fù)整數(shù),大值為65535;

  • rpm:版本不得包含-(破折號)字符。

  • deb:格式為 EPOCH:UPSTREAM_VERSION-DEBIAN_REVISION

    其中:EPOCH是一個可選的非負(fù)整數(shù);UPSTREAM_VERSION只包含字母數(shù)字和字符.,+,-,~,必須以數(shù)字開頭;DEBIAN_REVISION是可選的,可能只包含字母數(shù)字和字符.,+,~。

自定義 JDK 版本

由于該插件使用jpackage,所以最低得使用 JDK 15。

  • JAVA_HOME環(huán)境變量指向兼容的 JDK 版本。
  • javaHome通過 DSL 設(shè)置:
compose.desktop {
    application {
        javaHome = System.getenv("JDK_15")
    }
}
自定義輸出目錄

Compose Desktop默認(rèn)的打包路徑在 /build/compose/binaries/main/app 中,如果想修改下打包路徑的話,需要修改下配置:

compose.desktop {application {nativeDistributions {outputBaseDir.set(project.buildDir.resolve("customOutputDir"))
        }
    }
}
自定義基本數(shù)據(jù)

DSL 塊中提供以下屬性nativeDistributions

  • packageName— 應(yīng)用程序名稱(默認(rèn)值:Gradle 項目名稱);
  • version— 應(yīng)用程序的版本(默認(rèn)值:Gradle 項目的版本);
  • description— 應(yīng)用程序的描述(默認(rèn)值:無);
  • copyright— 應(yīng)用程序的版權(quán)(默認(rèn)值:無);
  • vendor— 應(yīng)用程序的供應(yīng)商(默認(rèn)值:無);
  • licenseFile— 應(yīng)用程序的許可證(默認(rèn)值:無)。
compose.desktop {application {nativeDistributions {packageName = "PlayWeather"
            version = "1.1.0"
            description = "PlayWeather"
            copyright = "? 2022 My Name. All rights reserved."
            vendor = "Example vendor"
            licenseFile.set(project.file("LICENSE.txt"))
        }
    }
}

這塊大家可以根據(jù)需求來定義這些數(shù)據(jù),如不需要不寫即可。

特定平臺選項

需要使用相應(yīng)的 DSL 塊設(shè)置特定于平臺的選項,使用方法就是上面maxOS、windows、linux,不同平臺可配置的選項都不太一樣!

  • 所有平臺

    • iconFile.set(File("PATH_TO_ICON"))— 應(yīng)用程序特定于平臺的圖標(biāo)的路徑。

    • packageVersion = "1.0.0"— 特定于平臺的包版本。

    • installationPath = "PATH_TO_INSTALL_DIR"默認(rèn)安裝目錄的絕對或相對路徑;在 Windows 上dirChooser = true,可用于啟用在安裝過程中自定義路徑。

  • Linux

    • packageName = "custom-package-name"覆蓋默認(rèn)的應(yīng)用程序名稱;

    • debMaintainer = "maintainer@example.com"— deb 包維護(hù)者的電子郵件;

    • menuGroup = "my-example-menu-group"— 應(yīng)用程序的菜單組;

    • appRelease = "1"— rpm 包的發(fā)布值,或 deb 包的修訂值;

    • appCategory = "CATEGORY"— rpm 包的組值,或 deb 包的部分值;

    • rpmLicenseType = "TYPE_OF_LICENSE"— rpm 包的一種許可證;

    • debPackageVersion = "DEB_VERSION"``Specifying package version— 特定于 deb 的包版本;

    • rpmPackageVersion = "RPM_VERSION"``Specifying package version— 特定于 rpm 的軟件包版本;

  • MacOS

    • bundleID — 唯一的應(yīng)用標(biāo)識符;

      • 只能包含字母數(shù)字字符 (A-Z,a-z,0-9)、連字符 (-) 和句點 (.) 字符;
      • com.mycompany.myapp建議使用反向 DNS 表示法(例如);
    • packageName— 應(yīng)用名稱;

    • dockName— 顯示在菜單欄、“關(guān)于”菜單項、??繖诘戎械膽?yīng)用程序名稱。packageName等于默認(rèn)情況下的名稱;

    • signing,notarization,provisioningProfile, 和runtimeProvisioningProfile— 詳見相應(yīng)教程;

    • appStore = true— 為 Apple App Store 構(gòu)建和簽名。至少需要 JDK 17;

    • appCategory— Apple App Store 的應(yīng)用類別。默認(rèn)值是public.app-category.utilities;

    • entitlementsFile.set(File("PATH_TO_ENTITLEMENTS"))— 包含簽名時使用的權(quán)利的文件路徑;

    • runtimeEntitlementsFile.set(File("PATH_TO_RUNTIME_ENTITLEMENTS"))— 包含在簽署 JVM 運行時時使用的權(quán)利的文件路徑;

    • dmgPackageVersion = "DMG_VERSION"— 一個特定于 dmg 的包版本(詳見參考資料部分);

    • pkgPackageVersion = "PKG_VERSION"— 特定于 pkg 的包版本(詳情請參閱參考資料部分);

    • packageBuildVersion = "DMG_VERSION"— 包構(gòu)建版本(詳見參考資料部分);

    • dmgPackageBuildVersion = "DMG_VERSION"— 特定于 dmg 的軟件包構(gòu)建版本(詳情請參閱參考資料部分);

    • pkgPackageBuildVersion = "PKG_VERSION"— 特定于 pkg 的包構(gòu)建版本;

    • infoPlist— 鏈接到別的程序。

  • Linux

    • console = true為應(yīng)用程序添加一個控制臺啟動器;
    • dirChooser = true允許在安裝過程中自定義安裝路徑;
    • perUserInstall = true允許在每個用戶的基礎(chǔ)上安裝應(yīng)用程序
    • menuGroup = "start-menu-group"將應(yīng)用程序添加到指定的開始菜單組;
    • upgradeUuid = "UUID"— 一個唯一的 ID,當(dāng)更新的版本比安裝的版本更新時,它使用戶能夠通過安裝程序更新應(yīng)用程序。對于單個應(yīng)用程序,該值必須保持不變;
    • msiPackageVersion = "MSI_VERSION"— 特定于 msi 的軟件包版本;
    • exePackageVersion = "EXE_VERSION"— 特定于 pkg 的包版本
修改應(yīng)用圖標(biāo)

這塊為什么要單獨拿出一大塊來說呢?因為這個問題中困擾了我好久。。。所以才。。。。

還記得之前文章中說了Window可組合項中可以設(shè)定Icon么,但當(dāng)時說的時候?qū)iT說了此Icon并非應(yīng)用程序的圖標(biāo)!因為應(yīng)用程序圖標(biāo)需要以特定于操作系統(tǒng)的格式提供:

  • .icns對于 macOS
  • .ico適用于 Windows
  • .png對于 Linux

看下代碼吧:

compose.desktop {application {nativeDistributions {macOS {iconFile.set(project.file("icon.icns"))
            }
            windows {iconFile.set(project.file("icon.ico"))
            }
            linux {iconFile.set(project.file("icon.png"))
            }
        }
    }
}

Linux中的png格式的圖片我們很常見,但是MacWindows中的格式是什么鬼。。。沒見過?。?/p>

如果知道這兩種文件格式的話大家直接跳過后面的部分即可,這里還需要注意的是這里的文件路徑指的是項目根目錄。

ICNS 文件
  1. 什么是.icns?

.icns是蘋果的 macOS 操作系統(tǒng)的 App 圖標(biāo)文件的擴(kuò)展名,大家在 macOS 的Desktop 桌面、Finder 訪達(dá)Dock 程序塢等看到應(yīng)用程序的外觀就是由一個內(nèi)置在此 App 內(nèi)部的擴(kuò)展名為.icns的文件實現(xiàn)的。

可以通過鼠標(biāo)“右鍵”點擊 App - “顯示包內(nèi)容” - 進(jìn)入Contents目錄 - 進(jìn)入Resources目錄,然后在目錄下可以找到名為Appicon.icns或其他后綴為.icns的一個圖標(biāo)文件。

  1. 如何創(chuàng)建.icns擴(kuò)展名的圖標(biāo)文件?

a. 準(zhǔn)備一張圖片,重命名為icon.png,其他大小尺寸可以通過終端命令生成;

b. 通過鼠標(biāo)右鍵或者命令,創(chuàng)建一個名為icons.iconset的文件夾

mkdir icons.iconset

c. 通過”終端“來快速創(chuàng)建各種不同尺寸要求的圖片文件

sips -z 512 512 icon.png -o icons.iconset/icon_512x512.png

d. ”終端“中運行下面的命令,就可以獲得名為icon.icns的圖標(biāo)文件了

iconutil -c icns icons.iconset -o icon.icns

注意:icon.png圖片文件和icons.iconset文件夾要保存在同一級目錄下,”終端“啟動后切換到相同目錄。

ICO 文件

ico文件是Windows系統(tǒng)的應(yīng)用圖標(biāo)格式,我也不會制作,但找到了一個制作ico的網(wǎng)站:

https://www.butterpig.top/icopro/

需要的話可以進(jìn)去制作。

混淆

Compose Desktop1.2 版本開始,Compose Gradle插件支持開箱即用的 ProGuard。ProGuard是一個眾所周知的用于縮小和混淆的開源工具Guardsquare。

Gradle插件為每個對應(yīng)的默認(rèn)打包任務(wù)提供了發(fā)布任務(wù):

默認(rèn)任務(wù)(沒有 ProGuard)發(fā)布任務(wù)(帶 ProGuard)描述
createDistributablecreateReleaseDistributable使用捆綁的 JDK 和資源創(chuàng)建應(yīng)用程序映像
runDistributablerunReleaseDistributable使用捆綁的 JDK 和資源運行應(yīng)用程序映像
runrunReleasejar使用 Gradle JDK運行非打包應(yīng)用程序
packagepackageRelease將應(yīng)用程序映像打包到文件中
packageForCurrentOSpackageReleaseForCurrentOS將應(yīng)用程序映像打包成與當(dāng)前操作系統(tǒng)兼容的格式
notarizenotarizeRelease上傳用于公證的應(yīng)用程序圖像(僅限 macOS)
checkNotarizationStatuscheckReleaseNotarizationStatus檢查公證是否成功(僅限 macOS)

默認(rèn)配置添加了一些 ProGuard 規(guī)則:

  • 縮小應(yīng)用程序圖像,即刪除未使用的類;
  • compose.desktop.application.mainClass用作入口點;
  • keep避免破壞Compose運行時的一些規(guī)則。

在許多情況下,獲得縮小的Compose應(yīng)用程序不需要任何額外的配置。但是,有時ProGuard可能無法跟蹤字節(jié)碼中的某些用法(例如,如果通過反射使用類,則可能會發(fā)生這種情況)。如果遇到僅在ProGuard處理后才會發(fā)生的問題,可能需要添加自定義規(guī)則。為此,通過 DSL 指定配置文件:

compose.desktop {
    application {
        buildTypes.release.proguard {
            configurationFiles.from(project.file("compose-desktop.pro"))
        }
    }
}

可以參考 Guardsquare 關(guān)于 ProGuard 規(guī)則和配置選項的綜合手冊。

默認(rèn)情況下禁用混淆。要啟用它,請通過 Gradle DSL 設(shè)置以下屬性:

compose.desktop {
    application {
        buildTypes.release.proguard {
            obfuscate.set(true)
        }
    }
}

混淆需要根據(jù)需要使用了,如果需要控制包體積的話盡量還是打開,可以減小包體積,還會減小代碼泄漏的可能性;反之打不打開都行!

實際操作

上面都是理論知識,咱們得實操??!有基礎(chǔ)知識之后實操就很簡單了,先來看下build.gradle.kts中的配置項吧:

compose.desktop {application {mainClass = "MainKt"
        nativeDistributions {targetFormats(TargetFormat.Dmg, TargetFormat.Exe, TargetFormat.Msi, TargetFormat.Deb)
            packageName = "PlayWeather"
            packageVersion = "1.0.0"
            description = "Play Weather App"
            copyright = "? 2022 My Name. All rights reserved."
            vendor = "Lenovo"
            licenseFile.set(project.file("LICENSE.txt"))
            modules("java.instrument", "java.management", "java.naming", "java.sql", "jdk.unsupported")

            linux {packageVersion = "1.0.0"
                debPackageVersion = "1.0.0"
                rpmPackageVersion = "1.0.0"
                // 設(shè)置圖標(biāo)
                iconFile.set(project.file("launcher/icon.png"))
            }
            macOS {packageVersion = "1.1.0"
                dmgPackageVersion = "1.1.0"
                pkgPackageVersion = "1.1.0"
                dockName = "PlayWeather"

                packageBuildVersion = "1.1.0"
                dmgPackageBuildVersion = "1.1.0"
                pkgPackageBuildVersion = "1.1.0"
                // 設(shè)置圖標(biāo)
                iconFile.set(project.file("launcher/icon.icns"))
            }
            windows {packageVersion = "1.2.0"
                msiPackageVersion = "1.2.0"
                exePackageVersion = "1.2.0"
                // 設(shè)置圖標(biāo)
                iconFile.set(project.file("launcher/icon.ico"))
            }
        }
        buildTypes.release.proguard {obfuscate.set(false)
            configurationFiles.from(project.file("proguard-rules.pro"))
        }
    }
}

這里的配置項就不多說了,上面都有過介紹,下面來打包吧!

在這里插入圖片描述

點擊上圖中藍(lán)色箭頭標(biāo)注的進(jìn)行打包,上面說過了,不能跨系統(tǒng)打包,Mac只能打Mac中使用的包。。雙擊執(zhí)行packageDmg任務(wù):

在這里插入圖片描述

沒問題的話大概會出現(xiàn)上圖的樣子,由于沒有配置自定義包路徑,所以還在默認(rèn)文件中,按照上面所描述的路徑進(jìn)行查看:

在這里插入圖片描述

復(fù)制文件路徑,在訪達(dá)中打開:

在這里插入圖片描述

雙擊進(jìn)行安裝即可:

在這里插入圖片描述

然后在資源庫中找到應(yīng)用雙擊打開應(yīng)該會遇到下面的錯誤:

在這里插入圖片描述

這時點擊取消,然后打開設(shè)置 ->隱私與安全性,往下滑:

在這里插入圖片描述

點擊箭頭標(biāo)注的“仍要打開”按鈕,會讓你輸入電腦的密碼,輸入完成后會彈出下面的對話框:

在這里插入圖片描述

點擊打開,這時應(yīng)用就能正常使用了。

在這里插入圖片描述

蘋果端就不打release包了,還需要蘋果的開發(fā)者賬號那一大堆。。。目前先能正常在Mac中運行吧!

總結(jié)

本文大概總結(jié)了下使用Compose Desktop如何進(jìn)行打包,此項目所有代碼都放到了Github中。

Github地址:https://github.com/zhujiang521/PlayWeather/tree/desktop

如果文中寫的有誤,歡迎在評論區(qū)提出,咱們一起探討。

文章如果能幫助到大家,哪怕是一點,我也非常高興,先這樣。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

文章標(biāo)題:ComposeDesktop初體驗之打包-創(chuàng)新互聯(lián)
當(dāng)前URL:http://muchs.cn/article30/dhdjpo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、網(wǎng)站收錄、網(wǎng)站建設(shè)電子商務(wù)、外貿(mào)建站軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)