Flutter 下載篇

2023-03-04 18:00:48

前言

本文是關於使用flutter_download_manager下載功能的實踐和探索。我們將基於flutter_download_manager的功能擴充套件,改造成自己想要的樣子。在閱讀本文之前,建議先了解前兩篇文章:

本文將基於第二篇中的擴充套件框架,將網路庫從dio切換為httpclient,並結合改造過程中發現的問題提出自己的想法。

優化點:dynamic的告警問題

在第2和20行中,黃色標記表明,如果第2行中的每個網路庫下載的返回值可能不同,則考慮將其設定為「dynamic」,這可能導致第20行中出現響應狀態碼的告警,因為該屬性可能不存在。

為了確保 download 介面的返回值具有 statusCode 屬性,在這裡定義了一個專門的返回類以進行限制。具體定義如下:

這樣就解決了statusCode告警問題,其中extra可以存放原始download response物件。

HttpClient實現網路庫

只用實現上一篇中的網路介面CustomHttpClient,然後修改IDownloader:createObject其中網路注入物件即可,如下:

//實現這個介面定義
abstract class CustomHttpClient {
  Future<DownloadHttpResponse> download(
    String urlPath,
    String savePath, {
    DownloadProgressCallback? onReceiveProgress,
    DownloadCancelToken? cancelToken,
    Map<String, dynamic>? options,
  });

  DownloadCancelToken generateToken();
}

------【idownloader.dart】----------
abstract class IDownloader {
  factory IDownloader() => createObject(
        //將這個注入修改成我們實現的即可 原來:customHttpClient: CustomDioImpl(),
        customHttpClient: CustomHttpClientImp(),
      );
}

實現程式碼:

  • 第9-17行:主要是將flutter_download_manager中已下載但未下載完整的檔案大小傳遞給後端,以便告知後端從哪裡繼續下載檔案。

如果不傳,會浪費頻寬和時間。在處理大檔案時,記憶體壓力會增大,中斷的可能性也會增加。此外,使用者介面可能會出現進度條跳躍的問題。

  • 第27-45行:將下載流寫入傳入的 savepath 檔案中。需要注意 cancelToken.isCancelled 方法,因為上一篇中沒有定義 isCancelled 屬性,這裡必須在 DownloadCancelToken 中提供該方法(第69行)。
  • 第55-65行:這裡實現了HttpClientCancelToken的cancel方法,具體實現就是給標誌位_isCancelled賦值。

遇到官方問題

完成上述實踐後,發現官方進度錯誤BUG。如果多次暫停、取消,然後再恢復下載,會出現進度起始位置錯誤的問題。下載會從已下載檔案的長度開始,效果如下所示:

DownloadManager依賴下載器,下載器依賴網路庫

三者間互動關係如下:

  • DownloadManager 通過維護列表來管理內部任務的增刪改查。每個任務對應一個下載過程。
  • Downloader 負責任務下載,並通過同步或非同步訊息通知當前下載任務的狀態。DownloadManger 通過這些訊息來更新任務列表。
  • Downloader 通過向網路庫傳送請求來下載任務。網路將結果返回給 Downloader,由 Downloader 來決定內部狀態和斷點續傳邏輯。

總結

本文介紹了Flutter下載功能的實踐和探索,包括網路庫的切換和優化。使用了httpclient實現網路庫,並解決了官方進度錯誤BUG。還回顧了flutter_download_manager的設計缺陷,並提出了下載框架的設計思路。總之,提供了有關Flutter下載功能的實用資訊和思考。

太棒了!鼓勵自己堅持到底。我希望我為你投入的時間增加了一些價值。

如果覺得文章對你有幫助,點贊、收藏、關注、評論,一鍵四連支援,你的支援就是我創作最大的動力。

❤️本文由公眾號程式設計黑板報 原創,關注我,獲取我的最新文章~❤️