您好,登錄后才能下訂單哦!
這篇文章主要介紹“Android基于Flutter如何編寫文件下載管理器”,在日常操作中,相信很多人在Android基于Flutter如何編寫文件下載管理器問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Android基于Flutter如何編寫文件下載管理器”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
Dio 的下載方法定義如下:
Future<Response> download( String urlPath, savePath, { ProgressCallback? onReceiveProgress, Map<String, dynamic>? queryParameters, CancelToken? cancelToken, bool deleteOnError = true, String lengthHeader = Headers.contentLengthHeader, data, Options? options, });
urlPath
:網絡資源的 url
;
savePath
:dynamic
類型,可以是下載后存儲文件路徑的字符串,也可以是一個返回字符串的回調方法(Dio 會把 headers
參數攜帶過去,方便針對下載返回內容構建文件路徑);
onReceiveProgress
:文件接收進度,是一個void Function(int count, int total)
回調函數,調用者可以通過該回調方法監測下載進度。
deleteOnError
:發生錯誤時候是否刪除已下載的文件,默認是 true。
lengthHeader
:源文件的實際大小(未壓縮前)。默認是 header
的content-length
。如果文件壓縮了,而沒有指定該值的話,那進度回調里的total
會是-1
;如果使用自定義的 header
指定了文件的大小,那么total
會是自定義的 header
對應的文件大小。
其他參數和普通的請求差不多,這里不再贅述。
為了不暴露下載的具體實現,我們在 http_util.dart
中封裝一個自己的下載方法。
static Future download( String url, String savePath, { Map<String, dynamic> queryParams, CancelToken cancelToken, dynamic data, Options options, void Function(int, int) onReceiveProgress, }) async { try { return await _dioInstance.download( url, savePath, queryParameters: queryParams, cancelToken: cancelToken, onReceiveProgress: onReceiveProgress, ); } on DioError catch (e) { if (CancelToken.isCancel(e)) { EasyLoading.showInfo('下載已取消!'); } else { if (e.response != null) { _handleErrorResponse(e.response); } else { EasyLoading.showError(e.message); } } } on Exception catch (e) { EasyLoading.showError(e.toString()); } }
我們新建一個文件下載頁面 file_download.dart
完成文件下載的示例。這里定義了幾個屬性來對文件下載過程進行反饋:
// 文件下載地址,這里是谷歌瀏覽器的下載地址(Mac 版本) String _downloadPath = 'https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg'; // 下載進度比例,用于檢測下載是否完成 double _downloadRatio = 0.0; // 下載進度百分比 String _downloadIndicator = '0.00%'; // 下載文件的存儲路徑 String _destPath; // 取消下載的 token CancelToken _token; // 指示當前是否處于下載中,以便做業務判斷 bool _downloading = false;
然后我們定義一個下載方法,在下載過程中如果 total
不為-1
就更新下載進度,否則提示錯誤(實際調試發現,如果涉及到需要驗證的,下載后后端實際會返回網頁,這樣也能下載網頁內容下來,但是不是想要的文件)。
void _downloadFile() { _token = CancelToken(); _downloading = true; HttpUtil.download(_downloadPath, _destPath, cancelToken: _token, onReceiveProgress: (int received, int total) { if (total != -1) { if (!_token.isCancelled) { setState(() { _downloadRatio = (received / total); if (_downloadRatio == 1) { _downloading = false; } _downloadIndicator = (_downloadRatio * 100).toStringAsFixed(2) + '%'; }); } } else { _downloading = false; EasyLoading.showError('無法獲取文件大小,下載失敗!'); } }); }
這里因為涉及到可能取消,因此只有在沒有取消的情況下才更新下載狀態,要不可能會出現取消的時候還處在下載接收字節的過程中,雖然取消了但是看到下載進度還在走的情況。
取消下載其實很簡單,當我們點擊取消按鈕的時候,調用 CancelToken
的cancel
方法即可。這里我們做了一個判斷,下載比例低于1才可以取消,因為下載完成再取消會拋出異常。同時取消后重置下載比例和顯示的下載百分比。
void _cancelDownload() { if (_downloadRatio < 1.0) { _token.cancel(); _downloading = false; setState(() { _downloadRatio = 0; _downloadIndicator = '0.00%'; }); } }
對于 App,沒有別的入口管理文件,因此實際過程中我們需要提供下載入口供用戶清理已下載的文件。實際已下載的文件,我們需要有下載文件管理功能供用戶管理文件,這個時候會需要本地存儲支撐,我們在后續的章節會介紹本地存儲。
刪除文件前需要判斷文件是否存在,如果文件不存在刪除可能拋出異常。文件的管理使用的是 dart:io 中的方法。
void _deleteFile() { try { File downloadedFile = File(_destPath); if (downloadedFile.existsSync()) { downloadedFile.delete(); } else { EasyLoading.showError('文件不存在'); } } catch (e) { EasyLoading.showError(e.toString()); } }
path_provider文件目錄管理
在 App 中沒法直接知道應用的文件存儲目錄,因此需要借用 path_provider 插件來獲取 App 的文件存儲目錄,path_provider
提供了如下方法:
getTemporaryDirectory
:應用臨時目錄(可能被清除)
getApplicationDocumentsDirectory
:應用文檔目錄(不會被系統清除,主要用戶數據存儲目錄),對于安卓推薦使用外部存儲getExternalStorageDirectory。
getApplicationSupportDirectory
:應用支持目錄,一般放置與用戶無關的數據。
getLibraryDirectory
:指向應用可以持久存儲數據的目錄,不支持安卓平臺。
getExternalStorageDirectory
:獲取外部存儲目錄,不支持 iOS 平臺。
getExternalCacheDirectories
:獲取外部緩存目錄,,不支持 iOS 平臺。
getExternalStorageDirectories
:獲取外部可以的目錄列表,不支持 iOS 平臺。
getDownloadsDirectory
:獲取下載目錄,用于 Web 端,不支持安卓和 iOS平臺。
通過 path_provider
拿到Directory
對象后,就可以通過 Directory
的 path
屬性獲取到完整的目錄路徑。本例我們是在 initialState 里獲取文件存儲路徑的,使用的是臨時目錄。
void initState() { getTemporaryDirectory() .then((tempDir) => {_destPath = tempDir.path + 'googlechrome.dmg'}); super.initState(); }
OS Error: Read-only file system
:安卓系統需要獲取READ_EXTERNAL_STORAGE
和WRITE_EXTERNAL_STORAGE
權限。同時需要使用 path_provider
獲取應用的文件目錄再往對應的目錄讀寫文件和訪問文件目錄。
onReceivedProgress
中如果total=-1
則表示該文件被壓縮或者需要會話信息才可以下載(如后端開啟了驗證)。
刪除文件的時候需要檢查文件是否在下載過程中,如果在下載過程中刪除會引起文件讀寫沖突,拋出異常。
CancelToken
一個實例只能取消一次請求,因此每次發起請求的時候需要重新構建CancelToken
對象,否則取消一次后無法再次取消。
運行結果如下圖所示:
到此,關于“Android基于Flutter如何編寫文件下載管理器”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。