最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android基于Flutter編寫文件下載管理器

 更新時間:2022年03月25日 15:34:16   作者:島上碼農(nóng)  
文件下載在很多類型的應(yīng)用中會涉及,例如音樂、文檔、包括圖片(只是圖片可以使用一些組件完成無感知的下載)。本篇介紹使用Flutter中的Dio下載方法完成文件的下載,需要的可以參考一下

前言

文件下載在很多類型的應(yīng)用中會涉及,例如音樂、文檔、包括圖片(只是圖片可以使用一些組件完成無感知的下載)。本篇介紹使用 Dio 的下載方法完成文件的下載,涉及到的內(nèi)容如下:

  • Dio 插件的 download 方法介紹;
  • 使用 download 的回調(diào)方法監(jiān)測下載進度;
  • 使用 CancelToken 取消正在下載的任務(wù);
  • 刪除已下載的文件;
  • path_provider 插件管理App文件目錄;
  • 下載文件調(diào)試過程中發(fā)現(xiàn)的一些問題;

Dio 的下載方法 download

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:網(wǎng)絡(luò)資源的 url;
  • savePathdynamic 類型,可以是下載后存儲文件路徑的字符串,也可以是一個返回字符串的回調(diào)方法(Dio 會把 headers 參數(shù)攜帶過去,方便針對下載返回內(nèi)容構(gòu)建文件路徑);
  • onReceiveProgress:文件接收進度,是一個void Function(int count, int total)回調(diào)函數(shù),調(diào)用者可以通過該回調(diào)方法監(jiān)測下載進度。
  • deleteOnError:發(fā)生錯誤時候是否刪除已下載的文件,默認是 true。
  • lengthHeader:源文件的實際大?。ㄎ磯嚎s前)。默認是 header 的content-length。如果文件壓縮了,而沒有指定該值的話,那進度回調(diào)里的total會是-1;如果使用自定義的 header 指定了文件的大小,那么total會是自定義的 header 對應(yīng)的文件大小。
  • 其他參數(shù)和普通的請求差不多,這里不再贅述。

為了不暴露下載的具體實現(xiàn),我們在 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());
??}
}

監(jiān)測下載進度

我們新建一個文件下載頁面 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;
//?指示當前是否處于下載中,以便做業(yè)務(wù)判斷
bool?_downloading?=?false;

然后我們定義一個下載方法,在下載過程中如果 total 不為-1就更新下載進度,否則提示錯誤(實際調(diào)試發(fā)現(xiàn),如果涉及到需要驗證的,下載后后端實際會返回網(wǎng)頁,這樣也能下載網(wǎng)頁內(nèi)容下來,但是不是想要的文件)。

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('無法獲取文件大小,下載失敗!');
????}
??});
}

這里因為涉及到可能取消,因此只有在沒有取消的情況下才更新下載狀態(tài),要不可能會出現(xiàn)取消的時候還處在下載接收字節(jié)的過程中,雖然取消了但是看到下載進度還在走的情況。

取消下載

取消下載其實很簡單,當我們點擊取消按鈕的時候,調(diào)用 CancelToken 的cancel方法即可。這里我們做了一個判斷,下載比例低于1才可以取消,因為下載完成再取消會拋出異常。同時取消后重置下載比例和顯示的下載百分比。

void?_cancelDownload()?{
??if?(_downloadRatio?<?1.0)?{
????_token.cancel();
????_downloading?=?false;
????setState(()?{
??????_downloadRatio?=?0;
??????_downloadIndicator?=?'0.00%';
????});
??}
}

刪除已經(jīng)下載的文件

對于 App,沒有別的入口管理文件,因此實際過程中我們需要提供下載入口供用戶清理已下載的文件。實際已下載的文件,我們需要有下載文件管理功能供用戶管理文件,這個時候會需要本地存儲支撐,我們在后續(xù)的章節(jié)會介紹本地存儲。

刪除文件前需要判斷文件是否存在,如果文件不存在刪除可能拋出異常。文件的管理使用的是 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 中沒法直接知道應(yīng)用的文件存儲目錄,因此需要借用 path_provider 插件來獲取 App 的文件存儲目錄,path_provider 提供了如下方法:

  • getTemporaryDirectory:應(yīng)用臨時目錄(可能被清除)
  • getApplicationDocumentsDirectory:應(yīng)用文檔目錄(不會被系統(tǒng)清除,主要用戶數(shù)據(jù)存儲目錄),對于安卓推薦使用外部存儲getExternalStorageDirectory。
  • getApplicationSupportDirectory:應(yīng)用支持目錄,一般放置與用戶無關(guān)的數(shù)據(jù)。
  • getLibraryDirectory:指向應(yīng)用可以持久存儲數(shù)據(jù)的目錄,不支持安卓平臺。
  • 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();
}

調(diào)試過程中遇到的一些錯誤

  • OS Error: Read-only file system:安卓系統(tǒng)需要獲取READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE權(quán)限。同時需要使用 path_provider獲取應(yīng)用的文件目錄再往對應(yīng)的目錄讀寫文件和訪問文件目錄。
  • onReceivedProgress 中如果total=-1則表示該文件被壓縮或者需要會話信息才可以下載(如后端開啟了驗證)。
  • 刪除文件的時候需要檢查文件是否在下載過程中,如果在下載過程中刪除會引起文件讀寫沖突,拋出異常。
  • CancelToken一個實例只能取消一次請求,因此每次發(fā)起請求的時候需要重新構(gòu)建CancelToken對象,否則取消一次后無法再次取消。

運行結(jié)果及代碼

運行結(jié)果如下圖所示:

屏幕錄制2021-07-24 下午9.59.04.gif

總結(jié)

從示例可以看到,Dio 的下載方法是簡單易用的,而且提供了友好的下載反饋。同時,借助 CancelToken 也能取消或者暫停下載(暫停時設(shè)置deleteOnError=false,表示不刪除文件,然后恢復(fù)到時候從已下載的偏移量開始,也可以按這種方式做斷點續(xù)傳,具體方式可以搜索或者自己完成)。Dio 網(wǎng)絡(luò)請求系列的詳細介紹到這一篇結(jié)束,后續(xù)實際業(yè)務(wù)用到的時候再穿插介紹,接下來一篇將對 Dio 系列文章做一個整體總結(jié)。

以上就是Android基于Flutter編寫文件下載管理器的詳細內(nèi)容,更多關(guān)于Android文件下載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android中使用自定義ViewGroup的總結(jié)

    Android中使用自定義ViewGroup的總結(jié)

    本篇文章主要介紹了Android中使用自定義ViewGroup的總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Android端代碼量非常小的分頁加載庫

    Android端代碼量非常小的分頁加載庫

    這篇文章主要給大家介紹了關(guān)于Android端代碼量非常小的分頁加載庫的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Android仿新浪微博啟動界面或登陸界面(1)

    Android仿新浪微博啟動界面或登陸界面(1)

    這篇文章主要為大家詳細介紹了Android仿新浪微博啟動界面或登陸界面的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android用代碼獲取手機root之后的最高權(quán)限

    Android用代碼獲取手機root之后的最高權(quán)限

    機得root之后通過代碼可以獲得最高權(quán)限如果沒有root的話請不要往下看,毫無意義,root之后的朋友可以參考下本文或許有意想不到的收獲
    2013-03-03
  • Android編程實現(xiàn)將ButtonBar放在屏幕底部的方法

    Android編程實現(xiàn)將ButtonBar放在屏幕底部的方法

    這篇文章主要介紹了Android編程實現(xiàn)將ButtonBar放在屏幕底部的方法,涉及Android界面設(shè)計與文本操作相關(guān)技巧,需要的朋友可以參考下
    2017-03-03
  • android 使用瀏覽器打開指定頁面的實現(xiàn)方法

    android 使用瀏覽器打開指定頁面的實現(xiàn)方法

    這篇文章主要介紹了android 使用瀏覽器打開指定頁面的實現(xiàn)方法,本文通過實例文字說明的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • Android精確測量文本寬高及基線位置的方法

    Android精確測量文本寬高及基線位置的方法

    這篇文章主要給大家介紹了關(guān)于Android精確測量文本寬高及基線位置的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Android刮刮卡效果實現(xiàn)代碼

    Android刮刮卡效果實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了Android刮刮卡效果實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • 詳解MVP模式在Android開發(fā)中的應(yīng)用

    詳解MVP模式在Android開發(fā)中的應(yīng)用

    MVP是MVC衍生而來的,很早以前就由某軟公司提出,近年來在Android應(yīng)用開發(fā)中越來越多的被提及,越來越重要了。這篇文章主要介紹了詳解MVP模式在Android開發(fā)中的應(yīng)用,有興趣的可以了解一下。
    2016-11-11
  • Android使用ViewPager實現(xiàn)屏幕滑動效果

    Android使用ViewPager實現(xiàn)屏幕滑動效果

    這篇文章主要為大家詳細介紹了Android使用ViewPager實現(xiàn)屏幕滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10

最新評論

石林| 宁明县| 应用必备| 枣强县| 盐亭县| 彩票| 巴林右旗| 丹东市| 凤山县| 靖边县| 乌拉特中旗| 靖远县| 讷河市| 泗洪县| 东阿县| 射洪县| 甘南县| 营山县| 阳春市| 沂源县| 全椒县| 当涂县| 镇赉县| 屯门区| 从化市| 林口县| 五峰| 谢通门县| 武山县| 鹤壁市| 鄂托克前旗| 永昌县| 乌拉特前旗| 包头市| 边坝县| 北安市| 连江县| 克拉玛依市| 旬邑县| 曲靖市| 健康|