从 0 到 1 搞一个 Compose Desktop 版本的玩天气之打包

news2024/11/24 4:11:20

从 0 到 1 搞一个 Compose Desktop 版本的玩天气之打包

大家好,前两篇文章大概介绍了下上手 Compose Desktop 和自定义绘制时遇到的一些问题,项目的最终实现效果如下:

视频

代码写好了,该弄的动画也弄了,该请求的网络数据也请求了,该实现的效果也都实现好了,但是!!!咱们得打包出来啊!不打包出来别人如何使用呢?难道说别人想用你开发的桌面应用,结果你给他说你先下载一个 IntelliJ Idae ,然后下载下我的源码,之后把环境配置好,最后运行就可以了!如果下次再想用的时候再运行一次就好了!

这说的是人话嘛😂,肯定不能这样,所以一定要打包!由于 Compose Desktop 不止可以运行在 Mac 中,还可以运行在 WindowsLinux 中,所以需要打多个包。那使用 Compose Desktop 应该如何打包呢?且听我慢慢道来!

基本用法

插件中的基本配置单元是一个 applicationapplication 是什么呢?在第一篇文章中也提到了,就是在 build.gradle.kts 文件中的代码,咱们再来看下:

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

一个 application 定义了一组最终二进制文件的共享配置。换句话说,application DSL 允许将一堆文件连同 JDK 分发包打包成一组各种格式(.dmg.deb.msi.exe等)的压缩二进制安装程序。

该插件创建以下任务:

  • package<FormatName>(例如 packageDmgpackageMsi)用于将应用程序打包成相应的格式。这块需要注意的是,目前没有交叉编译支持,因此只能使用特定操作系统构建格式(例如,要构建.dmg 就必须使用 macOS)。默认情况下会跳过与当前操作系统不兼容的任务。
  • packageDistributionForCurrentOS 是一个生命周期任务,聚合了应用程序的所有包任务。
  • packageUberJarForCurrentOS 用于创建单个 jar 文件,其中包含当前操作系统的所有依赖项。
  • run 用于在本地运行应用程序。需要定义一个 mainClass 包含该 main 函数的类。请注意, run 将启动具有完整运行时的非打包 JVM 应用程序。这比创建具有最小运行时间的紧凑二进制映像更快、更容易调试。要运行最终的二进制图像,需要改用 runDistributable
  • createDistributable 用于在不创建安装程序的情况下创建预打包的应用程序映像和最终应用程序映像。
  • runDistributable 用于运行预先打包的应用程序映像。
  • 只有在脚本中使用 blockproperty 时才会创建任务。

光这么说其实有点懵,来一张图大家就明白我说的是什么了!

在这里插入图片描述

是不是有点恍然大明白的感觉!直接点击 IntelliJ IDEA 右侧边栏的 Gradle ,就会出现这个侧边栏,然后点击 Task 中的 compose desktop 就会出现上面描述的那些任务。

打包配置

Compose Desktop 打包有很多的配置项,下面来分别看下。

配置包含的 JDK 模块

Gradle 插件使用 jlink 通过仅包含必要的 JDK 模块来最小化可分发的大小。

此时,Gradle 插件不会自动确定必要的 JDK 模块。未能提供必要的模块不会导致编译问题,但会导致在运行时出现 ClassNotFoundException 的错误。

如果在运行打包的应用程序或任务时遇到 ClassNotFoundException ,可以使用DSL 方法runDistributable 来配置包含额外的 JDK 模块,需要使用 modules 来配置。

可以通过手动或运行 suggestModules 任务来确定哪些模块是必需的。suggestModules 使用 jdeps 静态分析工具来确定可能缺少的模块。

如果安装包的大小不重要的话,可以使用 includeAllModulesDSL 属性简单地包括所有运行时模块作为替代。

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

这块在我打包的时候搜了好久!最后在 Issue 中找到了解决方案!

可用格式

以下格式可用于支持的操作系统:

  • macOS.dmg ( TargetFormat.Dmg)、 .pkg( TargetFormat.Pkg)
  • Windows.exe ( TargetFormat.Exe)、 .msi( TargetFormat.Msi)
  • Linux.deb ( TargetFormat.Deb)、 .rpm( TargetFormat.Rpm)

指定包版本

由于可以打多种不同的包,也有可能需要区分不同的版本,所以可以指定包的版本。如何指定的呢?来看代码:

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" 
            }
        }
    }
}

必须为本机分发包指定包版本,还可以使用以下 DSL 属性(按优先级降序排列):

  • nativeDistributions.<os>.<packageFormat>PackageVersion 指定单个包格式的版本;
  • nativeDistributions.<os>.packageVersion 指定单个目标操作系统的版本;
  • nativeDistributions.packageVersion 指定所有包的版本;

对于 macOS,还可以使用以下 DSL 属性指定构建版本(按优先级降序排列):

  • nativeDistributions.macOS.<packageFormat>PackageBuildVersion 指定单一包格式的构建版本;
  • nativeDistributions.macOS.packageBuildVersion 为所有 macOS 包指定构建版本。

需要注意的是,版本必须遵循以下规则:

  • dmgpkg :格式为 MAJOR.MINOR.PATCH

    其中:MAJOR是一个 > 0 的整数;MINOR是一个可选的非负整数;PATCH是一个可选的非负整数;

  • msiexe :格式为 MAJOR.MINOR.BUILD

    其中:MAJOR是一个非负整数,最大值为255;MINOR是一个非负整数,最大值为255;BUILD是一个非负整数,最大值为65535;

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

  • deb :格式为 EPOCH:UPSTREAM_VERSION-DEBIAN_REVISION

    其中:EPOCH是一个可选的非负整数;UPSTREAM_VERSION 只包含字母数字和字符., +, -, ~,必须以数字开头;DEBIAN_REVISION是可选的,可能只包含字母数字和字符., +, ~

自定义 JDK 版本

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

  • JAVA_HOME 环境变量指向兼容的 JDK 版本。
  • javaHome 通过 DSL 设置:
compose.desktop {
    application {
        javaHome = System.getenv("JDK_15")
    }
}

自定义输出目录

Compose Desktop 默认的打包路径在 /build/compose/binaries/main/app 中,如果想修改下打包路径的话,需要修改下配置:

compose.desktop {
    application {
        nativeDistributions {
            outputBaseDir.set(project.buildDir.resolve("customOutputDir"))
        }
    }
}

自定义基本数据

DSL 块中提供以下属性 nativeDistributions

  • packageName — 应用程序名称(默认值:Gradle 项目名称);
  • version — 应用程序的版本(默认值:Gradle 项目的版本);
  • description — 应用程序的描述(默认值:无);
  • copyright — 应用程序的版权(默认值:无);
  • vendor — 应用程序的供应商(默认值:无);
  • licenseFile — 应用程序的许可证(默认值:无)。
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"))
        }
    }
}

这块大家可以根据需求来定义这些数据,如不需要不写即可。

特定平台选项

需要使用相应的 DSL 块设置特定于平台的选项,使用方法就是上面 maxOSwindowslinux ,不同平台可配置的选项都不太一样!

  • 所有平台

    • iconFile.set(File("PATH_TO_ICON"))— 应用程序特定于平台的图标的路径。

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

    • installationPath = "PATH_TO_INSTALL_DIR" 默认安装目录的绝对或相对路径;在 Windows 上dirChooser = true,可用于启用在安装过程中自定义路径。

  • Linux

    • packageName = "custom-package-name" 覆盖默认的应用程序名称;

    • debMaintainer = "maintainer@example.com" — deb 包维护者的电子邮件;

    • menuGroup = "my-example-menu-group" — 应用程序的菜单组;

    • appRelease = "1" — rpm 包的发布值,或 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 — 唯一的应用标识符;

      • 只能包含字母数字字符 ( A-Z, a-z, 0-9)、连字符 ( -) 和句点 ( .) 字符;
      • com.mycompany.myapp 建议使用反向 DNS 表示法(例如);
    • packageName — 应用名称;

    • dockName — 显示在菜单栏、“关于”菜单项、停靠栏等中的应用程序名称。packageName 等于默认情况下的名称;

    • signing, notarization, provisioningProfile, 和runtimeProvisioningProfile— 详见相应教程;

    • appStore = true — 为 Apple App Store 构建和签名。至少需要 JDK 17;

    • appCategory — Apple App Store 的应用类别。默认值是 public.app-category.utilities

    • entitlementsFile.set(File("PATH_TO_ENTITLEMENTS")) — 包含签名时使用的权利的文件路径;

    • runtimeEntitlementsFile.set(File("PATH_TO_RUNTIME_ENTITLEMENTS")) — 包含在签署 JVM 运行时时使用的权利的文件路径;

    • dmgPackageVersion = "DMG_VERSION" — 一个特定于 dmg 的包版本(详见参考资料部分);

    • pkgPackageVersion = "PKG_VERSION" — 特定于 pkg 的包版本(详情请参阅参考资料部分);

    • packageBuildVersion = "DMG_VERSION" — 包构建版本(详见参考资料部分);

    • dmgPackageBuildVersion = "DMG_VERSION" — 特定于 dmg 的软件包构建版本(详情请参阅参考资料部分);

    • pkgPackageBuildVersion = "PKG_VERSION" — 特定于 pkg 的包构建版本;

    • infoPlist — 链接到别的程序。

  • Linux

    • console = true 为应用程序添加一个控制台启动器;
    • dirChooser = true 允许在安装过程中自定义安装路径;
    • perUserInstall = true 允许在每个用户的基础上安装应用程序
    • menuGroup = "start-menu-group" 将应用程序添加到指定的开始菜单组;
    • upgradeUuid = "UUID" — 一个唯一的 ID,当更新的版本比安装的版本更新时,它使用户能够通过安装程序更新应用程序。对于单个应用程序,该值必须保持不变;
    • msiPackageVersion = "MSI_VERSION" — 特定于 msi 的软件包版本;
    • exePackageVersion = "EXE_VERSION" — 特定于 pkg 的包版本

修改应用图标

这块为什么要单独拿出一大块来说呢?因为这个问题中困扰了我好久。。。所以才。。。。

还记得之前文章中说了 Window 可组合项中可以设定 Icon 么,但当时说的时候专门说了此 Icon 并非应用程序的图标!因为应用程序图标需要以特定于操作系统的格式提供:

  • .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 中的格式是什么鬼。。。没见过啊!

如果知道这两种文件格式的话大家直接跳过后面的部分即可,这里还需要注意的是这里的文件路径指的是项目根目录。

ICNS 文件

  1. 什么是 .icns ?

.icns 是苹果的 macOS 操作系统的 App 图标文件的扩展名,大家在 macOS 的 Desktop 桌面Finder 访达Dock 程序坞 等看到应用程序的外观就是由一个内置在此 App 内部的扩展名为.icns的文件实现的。

可以通过鼠标“右键”点击 App - “显示包内容” - 进入 Contents 目录 - 进入Resources 目录,然后在目录下可以找到名为 Appicon.icns 或其他后缀为 .icns 的一个图标文件。

  1. 如何创建 .icns 扩展名的图标文件?

a. 准备一张图片,重命名为 icon.png,其他大小尺寸可以通过终端命令生成;

b. 通过鼠标右键或者命令,创建一个名为 icons.iconset 的文件夹

mkdir icons.iconset

c. 通过”终端“来快速创建各种不同尺寸要求的图片文件

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

d. ”终端“中运行下面的命令,就可以获得名为icon.icns的图标文件了

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

注意:icon.png 图片文件和 icons.iconset 文件夹要保存在同一级目录下,”终端“启动后切换到相同目录。

ICO 文件

ico 文件是 Windows 系统的应用图标格式,我也不会制作,但找到了一个制作 ico 的网站:

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

需要的话可以进去制作。

混淆

Compose Desktop 1.2 版本开始,Compose Gradle 插件支持开箱即用的 ProGuard。ProGuard 是一个众所周知的用于缩小和混淆的开源工具Guardsquare。

Gradle插件为每个对应的默认打包任务提供了发布任务:

默认任务(没有 ProGuard)发布任务(带 ProGuard)描述
createDistributablecreateReleaseDistributable使用捆绑的 JDK 和资源创建应用程序映像
runDistributablerunReleaseDistributable使用捆绑的 JDK 和资源运行应用程序映像
runrunReleasejar使用 Gradle JDK运行非打包应用程序
package<FORMAT_NAME>packageRelease<FORMAT_NAME>将应用程序映像打包到<FORMAT_NAME>文件中
packageForCurrentOSpackageReleaseForCurrentOS将应用程序映像打包成与当前操作系统兼容的格式
notarize<FORMAT_NAME>notarizeRelease<FORMAT_NAME>上传<FORMAT_NAME>用于公证的应用程序图像(仅限 macOS)
checkNotarizationStatuscheckReleaseNotarizationStatus检查公证是否成功(仅限 macOS)

默认配置添加了一些 ProGuard 规则:

  • 缩小应用程序图像,即删除未使用的类;
  • compose.desktop.application.mainClass 用作入口点;
  • keep 避免破坏 Compose 运行时的一些规则。

在许多情况下,获得缩小的 Compose 应用程序不需要任何额外的配置。但是,有时 ProGuard 可能无法跟踪字节码中的某些用法(例如,如果通过反射使用类,则可能会发生这种情况)。如果遇到仅在 ProGuard 处理后才会发生的问题,可能需要添加自定义规则。为此,通过 DSL 指定配置文件:

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

可以参考 Guardsquare 关于 ProGuard 规则和配置选项的综合手册。

默认情况下禁用混淆。要启用它,请通过 Gradle DSL 设置以下属性:

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

混淆需要根据需要使用了,如果需要控制包体积的话尽量还是打开,可以减小包体积,还会减小代码泄漏的可能性;反之打不打开都行!

实际操作

上面都是理论知识,咱们得实操啊!有基础知识之后实操就很简单了,先来看下 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"
                // 设置图标
                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"
                // 设置图标
                iconFile.set(project.file("launcher/icon.icns"))
            }
            windows {
                packageVersion = "1.2.0"
                msiPackageVersion = "1.2.0"
                exePackageVersion = "1.2.0"
                // 设置图标
                iconFile.set(project.file("launcher/icon.ico"))
            }
        }
        buildTypes.release.proguard {
            obfuscate.set(false)
            configurationFiles.from(project.file("proguard-rules.pro"))
        }
    }
}

这里的配置项就不多说了,上面都有过介绍,下面来打包吧!

在这里插入图片描述

点击上图中蓝色箭头标注的进行打包,上面说过了,不能跨系统打包,Mac 只能打 Mac 中使用的包。。双击执行 packageDmg 任务:

在这里插入图片描述

没问题的话大概会出现上图的样子,由于没有配置自定义包路径,所以还在默认文件中,按照上面所描述的路径进行查看:

在这里插入图片描述

复制文件路径,在访达中打开:

在这里插入图片描述

双击进行安装即可:

在这里插入图片描述

然后在资源库中找到应用双击打开应该会遇到下面的错误:

在这里插入图片描述

这时点击取消,然后打开设置 -> 隐私与安全性,往下滑:

在这里插入图片描述

点击箭头标注的“仍要打开”按钮,会让你输入电脑的密码,输入完成后会弹出下面的对话框:

在这里插入图片描述

点击打开,这时应用就能正常使用了。

在这里插入图片描述

苹果端就不打 release 包了,还需要苹果的开发者账号那一大堆。。。目前先能正常在 Mac 中运行吧!

总结

本文大概总结了下使用 Compose Desktop 如何进行打包,此项目所有代码都放到了 Github 中。

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

如果文中写的有误,欢迎在评论区提出,咱们一起探讨。

文章如果能帮助到大家,哪怕是一点,我也非常高兴,先这样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91415.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】八大排序算法详解

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《数据结构》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 排序前言一…

汇编语言第一章:基础知识

1. 基础知识 机器语言 机器语言是机器指令的集合&#xff0c;是一台机器可以正确执行的命令。现在一般电子计算机的机器指令是一列二进制数字。机器指令集是机器语言。 汇编语言 机器语言难以辨别和记忆&#xff0c;所以产生了汇编语言。汇编语言的主体是汇编指令。 操作&…

on-device training

又搬来个好玩呃 说来又想试试了 , 仅用256KB就实现单片机上的神经网络训练&#xff08;training,notinference&#xff09;&#xff0c;从此终端智能不再是单纯的推理&#xff0c;而是能持续的自我学习自我进化 On-Device Training under 256KB Memory 说到神经网络训练&#…

编译原理实验四

编译原理实验四 实验要求 cminus-f的词法分析和语法分析部分已经完成&#xff0c;最终得到的是语法分析树。而为了产生目标代码&#xff0c;还需要将语法分析树转为抽象语法树&#xff0c;通过抽象语法分析树生成中间代码(即IR)&#xff0c;最后使用中间代码来进行优化并生成…

easyExcel导出表头合并 不得不说真牛

有个导出单元格合并的任务&#xff0c;表头不规则合并格式&#xff0c;看得就烦&#xff0c;尤其是对于没玩儿过合并的我来说&#xff0c;任务放在哪里不知咋做&#xff0c;网上也看了一堆合并的方法&#xff0c;自己写注解来写的那些&#xff0c;麻烦得要命&#xff0c;我写一…

48.python break语句-终止循环

48.break语句-终止循环 文章目录48.break语句-终止循环1.循环控制2.break的作用3. 语法4. 实操练习5. 知识扩展&#xff1a;print的位置6. break语句循环图1.循环控制 在循环的过程中如果要退出循环&#xff0c;我们可以用break语句和continue语句。 2.break的作用 break [b…

Android入门第49天-使用RadioGroup+Fragment来重构类首页底部4个按钮的界面

简介 我们在&#xff1a;Android入门第47天-Fragment的基本使用 中使用Fragment制作了一个类首页底部含4个按钮的界面。今天的课程我们要做的是把第47天里的代码中一部分共用的东西抽象到res/values/themes.xml文件中。另外我们使用RadioGroup天然的只有一个可以被选中来代替…

Python学习笔记-文件及文件夹操作

记述python中关于文件和目录的基本操作。 一、基本文件操作 1.文件的创建和打开 file open(filename[,mode[,buffering]]) file&#xff1a;文件对象filename&#xff1a;文件路径&#xff0c;字符串类型&#xff0c;若要打开的文件与程序文件在同一文件夹&#xff0c;可直…

OPengl学习(三)——绘制几何物体和状态管理

文章目录0、 写在前面1、绘图工具1.1、清除窗口1.2、指定颜色1.3、强制完成绘图1.4、坐标系统工具2、点&#xff0c;直线&#xff0c;多边形2.1、填充多边形3、点&#xff0c;直线&#xff0c;多边形细节刻画4、基本状态管理0、 写在前面 1、OpenGL自身是一个巨大的状态机(Sta…

【CELL】compass利用单细胞转录组+流平衡分析预测细胞代谢状态,促进免疫细胞代谢研究

细胞代谢调控正常细胞功能以及多种疾病状态的病理生理。最近&#xff0c;免疫细胞代谢研究&#xff08;immunometabolism&#xff09;成为一个研究热点&#xff0c;揭示了包括抗病毒免疫、自身免疫和抗肿瘤反应在内的炎症代谢调节。然而&#xff0c;由于代谢网络的规模和复杂性…

BIO、NIO、AIO理解(I/O模型)

IO模型(unix网络编程第一卷) unix有五种I/O模型&#xff0c;好像其他系统也差不多吧。 I/O模型主要是两个阶段&#xff1a;等待数据与把数据从内核空间复制到用户空间&#xff0c;然后根据这两个阶段的不同&#xff0c;分类出来下面几类I/O模型。 前四个是同步IO,最后一个是异…

高并发下你还敢用ArrayList?过来看看CopyOnWriteArrayList吧!

一、ArrayList线程不安全 在Java的集合框架中&#xff0c;想必大家对ArrayList肯定不陌生&#xff0c;单线程的情况下使用它去做一些CRUD的操作是非常方便的&#xff0c;先来看看这个例子&#xff1a; public class ListTest {public static void main(String[] args) {List&…

GIS基于智慧城市建设的作用

​​​​​智慧城市的建设对于改善居民的生活质量和提高城市的管理水平&#xff0c;有着公认的推动作用。其中&#xff0c;地理信息技术特别是GIS平台&#xff0c;在智慧城市的建设过程中扮演着关键角色。 在现实情况中&#xff0c;除了政策本身的一些因素&#xff0c;受限于一…

Web前端105天-day44-JSCORE

JSCORE04 目录 前言 一、复习 二、forEach 三、reduce 四、展开语法 五、解构语法 六、形参默认值 七、剩余参数 总结 前言 JSCORE04学习开始 一、复习 JS的第6个版本, 带来了大量的新特性, 新语法let/const : 两个新的声明变量的方式 新的作用域 脚本: 对应全局, 用…

RocketMQ中的线程池是如何创建的?

前言 大家好&#xff0c;今天主要来和大家聊一聊RocketMQ中的线程池是如何创建的&#xff0c;如何设置线程池数量&#xff0c;同时也可以从中去学习到一些线程池的实践和需要注意的一些细节。 RocketMQ在哪些地方使用到了线程池&#xff1f; 在RocketMQ中存在了大量的对线程…

学籍信息网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 学籍信息管理&#xff1a;添加信息、修改信息、删除信息、查询信息 添加信息&#xff0c;管理员根据学生的将信息导入系…

[附源码]Python计算机毕业设计高校师资管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

行业分析| 智慧头盔在快对讲上的应用与实践

快对讲综合调度系统是基于移动通信网络&#xff0c; 整合集群对讲、视频监控、实时音视频技术、PSTN、GIS定位、IM和调度业务的产品&#xff0c;为客户提供专业对讲、视频会议、可视化融合指挥调度等功能为一体的音视频实时交互平台。 快对讲和智慧头盔 智慧头盔&#xff0c;…

PHP实验室管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP实验室管理系统 是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为PHP APACHE&#xff0c;数据库为 mysql5.0&#xff0c;使用php语言开发。 PHP…

第10讲:vue脚手架集成axios

一、创建项目并添加axios支持 创建项目请参考&#xff1a;使用脚手架创建vue项目 创建路由项目请参考&#xff1a;路由开发 1.1、添加axios支持 使用如下命令添加axios支持 npm install axios //vue-cli2.0安装方式1.2、在main.js中引用并使用axios 使用如下命令 impor…