更新下載庫update絕對詳解

来源:http://www.cnblogs.com/LiuZhen/archive/2017/07/11/7027502.html
-Advertisement-
Play Games

下載更新apk,基本上每個app都需要的功能,來看看吧,肯定有你想要的,以前都是自己寫,近期想藉助第三方的一個庫來做,功能齊全,感覺不錯,記錄使用過程,雖然官方也有使用教程,不過畢竟粗略,網上也能搜到,不過基本都是複製的 首先下載庫,地址改成我們自己的,檢查地址就讓它了,這個根據自己的業務調整,也能 ...


 

下載更新apk,基本上每個app都需要的功能,來看看吧,肯定有你想要的,以前都是自己寫,近期想藉助第三方的一個庫來做,功能齊全,感覺不錯,記錄使用過程,雖然官方也有使用教程,不過畢竟粗略,網上也能搜到,不過基本都是複製的

首先下載庫,地址改成我們自己的,檢查地址就讓它了,這個根據自己的業務調整,也能自定義

接下來是參數介紹

參數大多數一看就懂,這裡介紹下md5效驗,此欄位為必填欄位,不過有的時候不想效驗,或者測試的時候想先調通了,然後在跟後臺溝通加上效驗,這樣就不能直接gradle配置引用了,得下載源碼,更改裡面的代碼了,不然就得按照文檔說明來

我想很多人都不願意一開始去搞什麼md5效驗,雖然它的demo是可以用的,不過還是得改成自己的才安心,但是改成自己的又會效驗失敗,你不傳又不行,所以沒辦法了,只能改源代碼

info.size欄位是下載大小,這是為了提示框展示作用,可以自己動態獲取

源代碼裡面很多回調,有點繞,不過代碼也就那麼點,找找也就找到了

此處是返回效驗結果,註釋掉代碼,然後return true就行了,命名預設是md5命名

然後還有後臺靜默下載,這裡也提供了靜默下載,然後在狀態欄里顯示進度

直接調用demo的方法就好了

立即下載回調download方法,下載是繼承asynctask下載

 

然後裡面的彈框比較簡單的alertdialog寫的,我覺得這樣簡單蠻好的,可是現實是殘酷的,很多都是需要自己定製彈框,調用介面獲取數據啊,加樣式啊,都是正常,那麼預設的肯定滿足不了你了,可是它是寫在庫裡面的,要改的話得自己另外寫,然後替換掉它寫的

我是自己寫了個幫助類,把它原來的註釋了

 

 progress也換成了自己了

它原本是在start裡面的,需求如此,只能改

還有一個就是強制更新功能,有的需求強制更新,初始化彈出提示更新框,然後調用介面獲取是否強制更新,如果是就點擊後臺靜默下載,可以正常操作界面,如果否,就彈出下載框下載,而它原本的強制更新不是這樣的,還有靜默下載,是不彈框的,直接就後臺下載了,這裡也好改,把一個判斷註釋掉就好了,找到強制更新判斷的地方

註釋後發現ok了,其它都不用改,下麵的doPrompt方法就是彈框下載,doDownload就是不彈框下載,這裡只是一個判斷,而真正是否靜默下載還是它原來的參數來決定的,所以把這裡改了參數正常傳進去,一切ok

 

最後就是md5驗證了,把伺服器的md5欄位傳進去,然後把前面註釋的代碼解開,這個要先跟後臺協商好,預設的是 String.format("%1$032x", new Object[]{var5}) ,寬度為32,我這邊伺服器上的是08x,所以要改一下

這裡網上的方法是與運算之類的,親自測了一下,沒有問題

我這裡還是用它預設的解密方法,把寬度改一下就好了,至於format用法也簡單

下麵是列印的日誌信息,看到輸出結果估計也就明白這是怎麼回事了

Log.e("format","08d "+String.format("%1$08d", 120504));
Log.e("format","08x "+String.format("%1$08x", 120504));
Log.e("format","016d "+String.format("%1$016d", 120504));
Log.e("format","016x "+String.format("%1$016x", 120504));

E/format: 08d 00120504
E/format: 08x 0001d6b8
E/format: 016d 0000000000120504
E/format: 016x 000000000001d6b8

運行程式,發現通過

 

然後不知道到這裡你們發現沒有,就是它初始化的時候會傳入一個checkurl,這裡其實就是你的介面地址,然後它自帶寫了一個網路訪問,再把請求後的數據設置到其中,提供下載操作,看它的下載操作就知道了

 1 @Override
 2     public void check(ICheckAgent agent, String url) {
 3         HttpURLConnection connection = null;
 4         try {
 5             connection = (HttpURLConnection) new URL(url).openConnection();
 6             connection.setRequestProperty("Accept", "application/json");
 7 
 8             if (mPostData == null) {
 9                 connection.setRequestMethod("GET");
10                 connection.connect();
11             } else {
12                 connection.setRequestMethod("POST");
13                 connection.setDoOutput(true);
14                 connection.setInstanceFollowRedirects(false);
15                 connection.setUseCaches(false);
16                 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
17                 connection.setRequestProperty("Content-Length", Integer.toString(mPostData.length));
18                 connection.getOutputStream().write(mPostData);
19             }
20 
21             if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
22                 agent.setInfo(UpdateUtil.readString(connection.getInputStream()));
23             } else {
24                 agent.setError(new UpdateError(UpdateError.CHECK_HTTP_STATUS, "" + connection.getResponseCode()));
25             }
26         } catch (IOException e) {
27             e.printStackTrace();
28             agent.setError(new UpdateError(UpdateError.CHECK_NETWORK_IO));
29         } finally {
30             if (connection != null) {
31                 connection.disconnect();
32             }
33         }
34     }

這就是最外層的check方法,url就是你傳入的checkurl,如果你不傳不用它的,就會出現空指針錯誤,然後在調用 agent.setInfo 設置值到 UpdateAgent 這個類裡面,這個類是具體的下載類了,為什麼講這個

我們自己肯定會有檢查更新的介面,肯定會傳入參數,回調肯定會做邏輯處理,在它裡面這樣實在不方便,它傳入的checkurl添加參數什麼的也得改,不喜歡,所以想把這個檢查更新的功能去掉,只要下載功能,檢查更新我們自己處理

改起來就有點大了,不像前面的那些,小改動,不過看懂了也好改,從最外層開始進入,你需要一個打開方式,外面這多設置調用方法,其實說到底就是傳入回調和數據進入,然後提供檢查更新和下載操作

最外層設置的數據在 UpdateManager 這個類裡面,點進入看就是了,最重要的就是check方法了

 1 public void check() {
 2             long now = System.currentTimeMillis();
 3             if (now - sLastTime < 3000) {
 4                 return;
 5             }
 6             sLastTime = now;
 7 
 8             if (TextUtils.isEmpty(mUrl)) {
 9                 mUrl = UpdateUtil.toCheckUrl(mContext, sUrl, sChannel);
10             }
11 
12             UpdateAgent agent = new UpdateAgent(mContext, mUrl, mIsManual, mIsWifiOnly, mNotifyId,isSilent);
13             if (mOnNotificationDownloadListener != null) {
14                 agent.setOnNotificationDownloadListener(mOnNotificationDownloadListener);
15             }
16             if (mOnDownloadListener != null) {
17                 agent.setOnDownloadListener(mOnDownloadListener);
18             }
19             if (mOnFailureListener != null) {
20                 agent.setOnFailureListener(mOnFailureListener);
21             }
22             if (mChecker != null) {
23                 agent.setChecker(mChecker);
24             } else {
25                 agent.setChecker(new UpdateChecker(mPostData));
26             }
27             if (mParser != null) {
28                 agent.setParser(mParser);
29             }
30             if (mDownloader != null) {
31                 agent.setDownloader(mDownloader);
32             }
33             if (mPrompter != null) {
34                 agent.setPrompter(mPrompter);
35             }
36             if (endListener != null){
37                 UpdateAgent.endListener = endListener;
38             }
39             agent.check();
40         }
41     }

在這個方法裡面可以看到,基本數據都轉移到了 UpdateAgent 這個類裡面去了,但是調試你會發現,你不傳入檢查地址url 通過不了,因為有這麼一段

這也好辦,把裡面的空指針處理下就好了,價格空指針判斷讓它繼續往下走,下麵就到了關鍵的步驟了

進入了這裡了,進入這裡面做什麼,在進去看

 1 void doCheck() {
 2         new AsyncTask<String, Void, Void>() {
 3             @Override
 4             protected Void doInBackground(String... params) {
 5                 if (mChecker == null) {
 6                     mChecker = new UpdateChecker();
 7                 }
 8                 mChecker.check(UpdateAgent.this, mUrl);
 9                 return null;
10             }
11 
12             @Override
13             protected void onPostExecute(Void aVoid) {
14                 doCheckFinish();
15             }
16         }.execute();
17     }

一步步進入,發現這裡就是http訪問checkurl了,然後回調返回數據給到 UpdateAgent這個類裡面去

 然後發現回到了 UpdateAgent這裡,這裡做更新下載操作,調用的也是外層傳入的數據UpdateInfo,那麼就好辦了,外層的檢查更新介面不要,http訪問去掉,然後因為我們在最外層已經有了 UpdateInfo 這個類了,所以可以直接傳進去,然後就可以跳過檢查這個步驟了

添加一個實體類,這也是它自帶的實體類,生成設置獲取方法

然後在最外層去掉不必要的方法,把實體類提出來直接設置進去

1 UpdateManager.create(context)
2                 .setManual(true)// 在設置界面點擊檢查更新
3                 .setNotifyId(998)//notify唯一標識
4                 .setUserInfo(info)
5                 .check();        

精簡很多了,接下來就是裡面修改了,前面就說了,check方法裡面是直接傳值的,那我們就不需要回調了,直接傳入進去

 1 public void check() {
 2             long now = System.currentTimeMillis();
 3             if (now - sLastTime < 3000) {
 4                 return;
 5             }
 6             sLastTime = now;
 7 
 8             if (TextUtils.isEmpty(mUrl)) {
 9                 mUrl = UpdateUtil.toCheckUrl(mContext, sUrl, sChannel);
10             }
11 
12             UpdateAgent agent = new UpdateAgent(mContext, mUrl, mIsManual, mIsWifiOnly, mNotifyId);
13             if (mOnNotificationDownloadListener != null) {
14                 agent.setOnNotificationDownloadListener(mOnNotificationDownloadListener);
15             }
16             if (mOnDownloadListener != null) {
17                 agent.setOnDownloadListener(mOnDownloadListener);
18             }
19             if (mOnFailureListener != null) {
20                 agent.setOnFailureListener(mOnFailureListener);
21             }
22             if (mChecker != null) {
23                 agent.setChecker(mChecker);
24             } else {
25                 agent.setChecker(new UpdateChecker(mPostData));
26             }
27             if (mParser != null) {
28                 agent.setParser(mParser);
29             }
30             if (mDownloader != null) {
31                 agent.setDownloader(mDownloader);
32             }
33             if (mPrompter != null) {
34                 agent.setPrompter(mPrompter);
35             }
36             if (endListener != null){
37                 UpdateAgent.endListener = endListener;
38             }
39             if (mInfo != null)
40                 agent.setInfo(mInfo);
41             agent.check();
42         }
43     }

當然,這裡上面判斷checkurl地址的還得加個空指針判斷,不然走不下去

然後就是修改關鍵地方了,跳過檢查步驟,直接下載了,因為我們數據都有了,不需要去用它的網路請求了

 1 void doCheck() {
 2         if (mUrl == null || mUrl.isEmpty()) {
 3 //            setInfo();
 4             doCheckFinish();//直接下載,不檢查
 5             return;
 6         }
 7         new AsyncTask<String, Void, Void>() {
 8             @Override
 9             protected Void doInBackground(String... params) {
10                 if (mChecker == null) {
11                     mChecker = new UpdateChecker();
12                 }
13                 mChecker.check(UpdateAgent.this, mUrl);
14                 return null;
15             }
16 
17             @Override
18             protected void onPostExecute(Void aVoid) {
19                 doCheckFinish();
20             }
21         }.execute();
22     }

下麵就是它啟動的網路訪問請求,所以我們直接在最上面給它截斷了,然後直接調用下載方法,因為我們在上面已經傳入了 UpdateInfo 實體進入了 UpdateAgent 類裡面, doCheckFinish 方法就在 UpdateAgent裡面,所以什麼都不用改,它就會自動根據參數需求更新下載了

 而且這還解決了一個問題,就是你用它自帶的檢查更新會導致網路慢的時候過好久才彈框出來,好像卡住了一樣,而直接跳過這個步驟就沒有這個問題了,直接開始下載,不然只有在它原基礎上加個載入彈框什麼的

到這裡就要結束了,(☄⊙ω⊙)☄

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • iframe的url可以前端任何地址,這樣就可能出現漏洞,如果釣魚網站通過js把src改成了危險地址,如果沒有監控,就會有很大隱患。所以監控iframe的url變化就是必須要解決的問題了。 第一印象的解決方案是通過setInterval輪詢監控,貌似不太理想了,而且有延遲。 千般搜索,終於找到了好的 ...
  • 初次嘗試微信小程式開發,在此寫下步驟以做記錄和分享。 1.在網上找了很多資料,發現這位知乎大神提供的資料非常全面。 鏈接 https://www.zhihu.com/question/50907897#answer-46908609 2.按照步驟安裝微信開發者工具以及註冊用戶搭建環境,詳細步驟見鏈接 ...
  • 轉載請標明原文鏈接:http://www.cnblogs.com/zhanggui/p/7151795.html 前言 上一篇文章對App Extension做了簡單介紹以及對Share Extension的使用做了簡單說明,本篇文章主要是對Sticker Pack Extension進行介紹。 開 ...
  • 我們對於IOS的瞭解最多應該就是蘋果手機獨有的IOS系統吧,也可以說是單任務管理器,這可以說是一個優勢,但是隨著技術提升IOS慢慢有被超越的趨勢,但是很多大公司還是需要這方面的開發人才,那麼今天我們來談談IOS開發的入門所需要要具備的知識和技能,如果想要成為一個高薪技術人才那麼你們就要努力了。 一基 ...
  • javaMail,是提供給開發者處理電子郵件相關的編程介面。它是Sun發佈的用來處理email的API。它可以方便地執行一些常用的郵件傳輸。我們可以基於JavaMail開發出類似於Microsoft outlook的應用程式。JavaMail是可選包,因此如果需要使用的話你需要首先從java官網上下 ...
  • 1. 下載Charles Proxy 4.1.4版本,百度雲盤下載或去官網下載 2. 安裝後先打開Charles一次(Windows版可以忽略此步驟) 3. 在這個網站(http://charles.iiilab.com/)下載破解文件 charles.jar 4. 替換掉原文件夾里的charles ...
  • UICollectionView實現瀑布流 在iOS中可以實現瀑布流的目前已知的有2種方案: 本文中我們介紹第二種實現方案首先我們需要自定義一個繼承於UICollectionViewLayout的layout,然後需要重寫四個方法: 第一個方法是做一些初始化的操作,這個方法必須先調用一下父類的實現第 ...
  • 1. drawRect: UIView子類重寫 2. drawLayer: inContext: CALayer設置代理 (這是個代理方法) 3. drawInContext: CALayer子類重寫 4. 使用圖形上下文生成圖片: imageContext 儘量避免混用 實現 drawRect : ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...