JavaFX桌面應用-版本升級


好久沒有寫博客,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桌面應用-版本升級”獲取。

HiIT青年
關注公眾號,閱讀更多文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM