1. 程式人生 > >JavaFX桌面應用-版本升級

JavaFX桌面應用-版本升級

好久沒有寫部落格,2021年就以 “JavaFX桌面應用-版本升級” 開篇吧,記錄一下JavaFX應用版本升級的開發流程。 > 桌面應用升級的方案應該很多,這裡只是自己想到的方案。 ## 1. 效果展示 首先,先看一下版本升級的最終效果(先不討論UI美不美觀的問題,UI美化可以檢視其他部落格) ![](https://img2020.cnblogs.com/blog/2083963/202102/2083963-20210228090223006-1000667454.png) 如上圖,程式啟動後會自動檢測是否有最新版本,如果用則提示使用者,由使用者決定是否進行應用升級,如果使用者點選了升級,則會啟動升級程式進行升級,並在升級後重新啟動新版的APP。 ![](https://img2020.cnblogs.com/blog/2083963/202102/2083963-20210228103734026-1862891104.png) ## 2. 升級流程 在展開說明具體的功能開發前,簡單介紹一下應用升級的流程,以及涉及的各個端。 這裡的應用升級主要涉及3個方面: - App(主應用) - 升級SDK(封裝升級流程,App整合即可) - 升級程式(負責App升級) 應用升級的流程其實比較簡單,大致分為這幾個步驟: 1. 獲取最新版本資訊 2. 詢問使用者是否升級 3. 執行版本升級 升級的流程如下圖所示: ![](https://img2020.cnblogs.com/blog/2083963/202102/2083963-20210228091613012-1724728028.png) ## 3. 升級細節 在上面的升級流程看起來沒有什麼問題,但實際應用起來有一些細節需要注意,比如: - 版本怎麼計算 - 升級程式怎麼獲取更新包 - 升級程式怎麼開啟APP 一般來說,升級程式開發完成後可能很少修改,或者說,希望只開發一個升級程式,供所有app升級使用,這樣就不需要為每一個應用都開發一個升級程式。 ![](https://img2020.cnblogs.com/blog/2083963/202102/2083963-20210228093038031-1334103486.png) 上圖是升級程式獲取更新包的流程,這裡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提供合適的升級版本資訊及更新包。 版本計算簡要程式碼如下: ```java 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通過定義一些常量來記錄: ```java 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版本號常量 對應的版本計算實現程式碼如下: ```java 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檔案的情況。 ```java // 這裡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青年](https://images.cnblogs.com/cnblogs_com/itqn/1797476/o_200702010008qrcode.jpg) **關注公眾號**,閱讀更多文章。