好久没有写博客,2021年就以 “JavaFX桌面应用-版本升级” 开篇吧,记录一下JavaFX应用版本升级的开发流程。

桌面应用升级的方案应该很多,这里只是自己想到的方案。

1. 效果展示

首先,先看一下版本升级的最终效果(先不讨论UI美不美观的问题,UI美化可以查看其他博客)

如上图,程序启动后会自动检测是否有最新版本,如果用则提示用户,由用户决定是否进行应用升级,如果用户点击了升级,则会启动升级程序进行升级,并在升级后重新启动新版的APP。

2. 升级流程

在展开说明具体的功能开发前,简单介绍一下应用升级的流程,以及涉及的各个端。

这里的应用升级主要涉及3个方面:

  • App(主应用)
  • 升级SDK(封装升级流程,App集成即可)
  • 升级程序(负责App升级)

应用升级的流程其实比较简单,大致分为这几个步骤:

  1. 获取最新版本信息
  2. 询问用户是否升级
  3. 执行版本升级

升级的流程如下图所示:

3. 升级细节

在上面的升级流程看起来没有什么问题,但实际应用起来有一些细节需要注意,比如:

  • 版本怎么计算
  • 升级程序怎么获取更新包
  • 升级程序怎么打开APP

一般来说,升级程序开发完成后可能很少修改,或者说,希望只开发一个升级程序,供所有app升级使用,这样就不需要为每一个应用都开发一个升级程序。

上图是升级程序获取更新包的流程,这里SDK和升级程序是通过本地文件update_info作为通讯的媒介,具体的流程为:

  1. APP启动后调用SDK向服务器拉取版本信息,并将拉取版本信息的地址写入到本地文件update_info
  2. 如果发现有新版本,并且用户同意升级,那么启动升级程序
  3. 升级程序启动后,从本地文件update_info读取获取获取版本信息的地址,从服务器获取版本信息及更新包,执行版本更新

这里为什么需要SDK每一次都把获取版本信息的地址写入到本地文件中呢?就如上面所说的,升级程序可以是通用的,但每一个APP获取版本信息的地址是不同的,另外同一个APP不同版本获取版本信息的地址也可能是不同的(比如服务器在某个时间点更换了域名等等)。

升级程序和SDK的通讯解决了,整理流程也没有什么大问题,那么版本应该怎么计算呢?

最简单的处理方式就是,发现版本号不一样时就升级,这种方式不是不可以,但是可能会有很多问题,因为有些时候APP可能更新了一些不兼容旧版的功能,对于兼容的情况可以选择增量更新APP,而对于不兼容的情况就需要全量更新APP了,而且不排除让用户重新安装程序的情况。

这里介绍一下自己使用的一种方案,版本号规范约定为 x.y.z,客户端APP将x.y.z转化为整数(x*100+y*10+z)与服务器返回的版本进行比较,如果APP的版本小于服务版本则进行升级,服务端可以根据客户端提供的x.y.z提供合适的升级版本信息及更新包。

版本计算简要代码如下:

private int versionToInt(String version) {
String[] items = version.split("\\.");
int versionInt = 0;
for (String item : items) {
versionInt *= 10;
versionInt += Integer.parseInt(item.trim());
}
return versionInt;
}

所以每一个APP都得提供自己的版本号以及获取最新版本的接口地址,这个可以在APP通过定义一些常量来记录:

public interface Version {
// 获取版本的接口地址
String versionUri = "http://localhost:8090/itqn/version";
// 当前版本号
String version = "1.0.0";
}

这样,程序就可以每次启动后获取自己版本号,再从服务器获取版本信息计算是否需要升级,但是这样对有“跳过版本”这种升级流程来说是有问题的,按照上面的流程,当用户点击了“跳过版本”后,下次启动APP时,从服务器获取升级信息计算后仍需要升级,会弹出升级提示,这样很不友好。

这里稍微调整一下读取版本的流程:

  1. 用户点击跳过版本后,将最新版本号写入到本地文件version
  2. APP正常升级后,升级程序也将最新版本号写入到本地文件version
  3. 程序启动的时候,优先读取本地文件version的版本号进行计算,如果本地没有version文件,才读取APP版本号常量

对应的版本计算实现代码如下:

private void checkVersion() {
int curVersion = 0;
File f = new File("version");
char[] buf = new char[30];
try (FileReader fr = new FileReader(f)) {
int ret = fr.read(buf);
curVersion = versionToInt(new String(buf, 0, ret));
} catch (Exception ignore) {
// use AppVersion if occur exception
}
if (curVersion == 0) {
curVersion = versionToInt(Version.version);
}
UpdateExecutor.execute(Version.versionUri, curVersion);
}

最后,关于升级程序怎么打开APP这个问题可以参考升级程序和SDK的通讯方案。当然也用更新简单的方案,就是升级程序打开非自己名称的exe应用,这种方式只能用于应用程序只有一个exe文件的情况。

// 这里ITQN_update是升级程序的名称
File[] fs = new File(".").listFiles((dir, name) -> name.endsWith(".exe") && !name.equals("ITQN_update.exe"));
if (fs != null && fs.length > 0) {
try {
Desktop.getDesktop().open(fs[0]);
} catch (IOException e) {
new Alert(Alert.AlertType.ERROR, e.getMessage()).show();
}
}

应用升级这一块涉及的问题比较多,更多的细节可以通过公众号获取源码,具体阅读源码吧,展开说明的话太多了。

=========================================================

关注 公众号 “HiIT青年” 阅读推文“JavaFX桌面应用-版本升级”,文章底部可以获取源码。



关注公众号,阅读更多文章。

JavaFX桌面应用-版本升级的更多相关文章

  1. JavaFX桌面应用-MVC模式开发,“真香”

    使用mvc模块开发JavaFX桌面应用在JavaFX系列文章第一篇 JavaFX桌面应用开发-HelloWorld 已经提到过,这里单独整理使用mvc模式开发开发的流程. ~ JavaFX桌面应用开发 ...

  2. JavaFX桌面应用开发-HelloWorld

    JavaFX是一个强大的图形和多媒体处理工具包集合,它允许开发者来设计.创建.测试.调试和部署富客户端程序,并且和Java一样跨平台. JavaFX比Swing好用很多,它允许开发使用FXML来设计和 ...

  3. JavaFX桌面应用-为什么应用老是“未响应”

    日常使用软件的过程中,偶尔会遇到软件突然卡住,再点击几次就变成"未响应"的情况. 在JavaFX应用中同样也会出现这种情况,在开发过程中应该尽量避免这种情况的出现. >> ...

  4. JavaFX桌面应用开发系列文章

    ~ JavaFX桌面应用开发系列文章汇总篇 ~ JavaFX桌面应用开发-HelloWorld JavaFX布局神器-SceneBuilder JavaFX让UI更美观-CSS样式 JavaFX桌面应 ...

  5. JavaFX桌面应用-视频转码工具(支持爱奇艺qsv转mp4)

    最近由于需要将在爱奇艺下载的视频(qsv)转化了mp4,用JavaFX开发一个视频转码工具,算是JavaFX开发的第一个应用吧. 支持qsv转码mp4,理论上支持各种格式,仅测试了flv,qsv格式. ...

  6. JavaFX桌面应用-loading界面

    上次使用JavaFX开发了一个视频转码工具,当用户点击"启动"按钮开始转码的时候,会禁用启动按钮,防止多次启动转码. 这种处理方式对用户来说可能并是很友好,其实可以在启动转码的时弹 ...

  7. JavaFX桌面应用-SpringBoot + JavaFX

    SpringBoot对于Java程序员来说可以是一个福音,它让程序员在开发的时候,大大简化了各种spring的xml配置. 那么在JavaFX项目使用SpringBoot会是怎么样的体验呢? 这次使用 ...

  8. JavaFX桌面应用-构建程序框架

    看到JavaFX应用很多人都会说JavaFX应用太丑了,确实JavaFX比起Qt.MFC.Delphi这些界面确实丑了一点,但也不是没有可以美化的空间. 跟网页一样,单纯HTML不加任何CSS的时候也 ...

  9. JavaFX桌面应用开发-鼠标事件和键盘事件

    鼠标相关事件的操作初始代码 package application; import javafx.application.Application;import javafx.event.ActionE ...

随机推荐

  1. HDU4366 Successor【dfs序 分块】

    HDU4366 Successor 题意: 给出一棵根为\(1\)的树,每个点有两个权值\(x,y\),每次询问一个点的子树中\(x\)比这个点的\(x\)大且\(y\)值最大的那个点 题解: 如果以 ...

  2. 【bzoj 3232】圈地游戏(算法效率--01分数规划+图论--最小割)

    题目:DZY家的后院有一块地,由N行M列的方格组成,格子内种的菜有一定的价值,并且每一条单位长度的格线有一定的费用.DZY喜欢在地里散步.他总是从任意一个格点出发,沿着格线行走直到回到出发点,且在行走 ...

  3. 使用eclipse搭建第一个java web应用

    一. 首先是eclipse得下载,你要下载Eclipse IDE for Java EE这种类型的,我之前下载的Eclipse IDE for Enterprise Java Developers是官 ...

  4. Educational Codeforces Round 95 (Rated for Div. 2) A. Buying Torches (数学)

    题意:刚开始你有一个木棍,造一个火炬需要一个木根和一个煤块,现在你可以用一个木棍换取\(x\)个木棍,或者\(y\)根木棍换一个煤块,消耗一次操作,问最少需要操作多少次才能造出\(k\)把火炬. 题解 ...

  5. Codeforces Round #653 (Div. 3) E1. Reading Books (easy version) (贪心,模拟)

    题意:有\(n\)本书,A和B都至少要从喜欢的书里面读\(k\)本书,如果一本书两人都喜欢的话,那么他们就可以一起读来节省时间,问最少多长时间两人都能够读完\(k\)本书. 题解:我们可以分\(3\) ...

  6. c语言实现链表增、删、改、查及文件读写 && 链表实现程序

    一.链表实现增删改查 1.链表定义 1 #include<stdio.h> 2 #include<string.h> 3 #include<windows.h> 4 ...

  7. ES索引Index相关操作&ES数据类型、字符串类型text和keyword区别

    1.查看索引以及删除之前的测试索引 1. 查看索引以及索引数量信息 liqiang@root MINGW64 ~/Desktop $ curl -X GET http://127.0.0.1:9200 ...

  8. github 无法访问

    描述: 1. ping 丢失 100% 2. git 失败 Failed to connect to github.com port 443: Timed out 3.打开网站 超时 解决: http ...

  9. Inkscape tricks

    Draw straight lines: click pencil button -> click once on your canvas(starting point) -> click ...

  10. KMP 算法 & 字符串查找算法

    KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of character ...