日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Flutter 异常处理之图片篇

發(fā)布時(shí)間:2024/4/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flutter 异常处理之图片篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

說(shuō)到異常處理,你可能直接會(huì)認(rèn)為不就是 try-catch 的事情,至于寫一篇文章單獨(dú)來(lái)說(shuō)明嗎?

如果你是這么想的,那么本篇說(shuō)不定會(huì)給你驚喜哦~

而且本篇聚焦在圖片的異常處理。

場(chǎng)景

學(xué)以致用,有具體的應(yīng)用場(chǎng)景,能夠加深我們對(duì)知識(shí)的掌握。

我們以簡(jiǎn)書的文章列表為例,如下圖:

假設(shè)產(chǎn)品有這樣的需求,當(dāng)右邊的封面圖加載失敗的時(shí)候,用一個(gè)默認(rèn)圖片替換或者直接讓文本橫向填充原有圖片位置。

不管處理方式是怎樣,首先我們要做的就是能夠知道圖片加載失敗。

如何獲知圖片加載失敗呢?下面我們通過(guò) Flutter 自帶網(wǎng)絡(luò)加載 API 和一個(gè)第三方網(wǎng)絡(luò)庫(kù)來(lái)進(jìn)行對(duì)比說(shuō)明。

Image.network

我們看下源碼,如下:

Image.network(String src, {Key key,double scale = 1.0,this.semanticLabel,this.excludeFromSemantics = false,this.width,this.height,this.color,this.colorBlendMode,this.fit,this.alignment = Alignment.center,this.repeat = ImageRepeat.noRepeat,this.centerSlice,this.matchTextDirection = false,this.gaplessPlayback = false,this.filterQuality = FilterQuality.low,Map<String, String> headers,}) : image = NetworkImage(src, scale: scale, headers: headers),assert(alignment != null),assert(repeat != null),assert(matchTextDirection != null),super(key: key);

可以看到只有 src 是必填參數(shù),因此我們給出 src 為不同值的情況。

1.一個(gè)圖片的 url

Widget _buildWidget() {return Image.network('https://upload-images.jianshu.io/upload_images/5361063-e413832da0038304.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800');}

能夠正常顯示如下圖:

2.不可訪問 url,如隨便一個(gè)字符串 test

Widget _buildWidget() {return Image.network('test');}

終端報(bào)錯(cuò)如下:

flutter: ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════ flutter: The following ArgumentError was thrown resolving an image codec: flutter: Invalid argument(s): No host specified in URI file:///test

模擬器顯示空白。

這種場(chǎng)景假設(shè)我們要捕獲異常,增加 try-catch,如下:

Widget _buildWidget() {try {return Image.network('test');} catch (e) {print('enter catch exception start');print(e);print('enter catch exception end');return Container();}}

依然沒法捕獲

3.可訪問非圖片 url,比如 http://mp.weixin.qq.com/mp/homepage?__biz=MzI3OTAyNzAwNg==&hid=5&sn=7e4598d8b00537fe2846f2e85d746b9a&scene=18#wechat_redirect

Widget _buildWidget() {try {return Image.network('http://mp.weixin.qq.com/mp/homepage?__biz=MzI3OTAyNzAwNg==&hid=5&sn=7e4598d8b00537fe2846f2e85d746b9a&scene=18#wechat_redirect');} catch (e) {print('enter catch exception start');print(e);print('enter catch exception end');return Container();}}

控制臺(tái)拋出如下異常

[VERBOSE-2:codec.cc(97)] Failed decoding image. Data is either invalid, or it is encoded using an unsupported format. flutter: ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════ flutter: The following _Exception was thrown resolving an image codec: flutter: Exception: operation failed

可以看到 try-catch 一樣沒法生效。沒有打印相關(guān)日志。

cached_network_image

這是一個(gè)第三方開發(fā)的網(wǎng)絡(luò)庫(kù),pub 地址為 https://pub.dartlang.org/packages/cached_network_image

因?yàn)轫?xiàng)目有用到這個(gè)庫(kù),所以用這個(gè)來(lái)舉例,并不是為其打廣告,至于你實(shí)際開發(fā)是否用這個(gè)庫(kù),還是有其他更好的庫(kù),需要你自己去評(píng)估。

因?yàn)檫@個(gè)是項(xiàng)目組 iOS 同事選擇的,我這邊并沒有深入研究過(guò)。

我們仿照上面的依次執(zhí)行 3 種 case。

1.一個(gè)圖片的 url

Widget _buildWidget() {return Image(image: new CachedNetworkImageProvider('https://upload-images.jianshu.io/upload_images/5361063-e413832da0038304.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800'));}

能夠正常顯示如下圖:

2.不可訪問 url,如隨便一個(gè)字符串 test

Widget _buildWidget() {return Image(image: new CachedNetworkImageProvider('test'));}

終端報(bào)錯(cuò)如下:

flutter: ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════ flutter: The following message was thrown resolving an image codec: flutter: Couldn't download or retrieve file.

模擬器顯示空白。

這種場(chǎng)景假設(shè)我們要捕獲異常,增加 try-catch,如下:

Widget _buildWidget() {try {return Image(image: new CachedNetworkImageProvider('test'));} catch (e) {print('enter catch exception start');print(e);print('enter catch exception end');return Container();}}

依然沒法捕獲。

但是我們通過(guò)其自帶的錯(cuò)誤回調(diào),如下:

Widget _buildWidget() {return Image(image: new CachedNetworkImageProvider('test',errorListener: () {print('enter errorListener');}));}

可以看到控制臺(tái)進(jìn)入了 errorListener,打印了對(duì)應(yīng)日志。

雖然 Flutter 自帶的錯(cuò)誤日志依然輸出了,但是通過(guò) errorListener 我們可以獲得這種異常情況。

flutter: enter errorListener flutter: ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════ flutter: The following message was thrown resolving an image codec: flutter: Couldn't download or retrieve file.

3.可訪問非圖片 url,比如 http://mp.weixin.qq.com/mp/homepage?__biz=MzI3OTAyNzAwNg==&hid=5&sn=7e4598d8b00537fe2846f2e85d746b9a&scene=18#wechat_redirect

Widget _buildWidget() {return Image(image: new CachedNetworkImageProvider('http://mp.weixin.qq.com/mp/homepage?__biz=MzI3OTAyNzAwNg==&hid=5&sn=7e4598d8b00537fe2846f2e85d746b9a&scene=18#wechat_redirect',errorListener: () {print('enter errorListener');}));}

運(yùn)行,控制臺(tái)會(huì)報(bào)錯(cuò),并且沒法捕獲,控制臺(tái)輸出如下:

[VERBOSE-2:codec.cc(97)] Failed decoding image. Data is either invalid, or it is encoded using an unsupported format. flutter: ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════ flutter: The following _Exception was thrown resolving an image codec: flutter: Exception: operation failed

使用 try-catch 也是一樣,這里就不贅余了。

圖片通用異常捕獲處理

通過(guò)上面的學(xué)習(xí),我們可以發(fā)現(xiàn)不管是 Image.network 還是 cached_network_image 沒法覆蓋全上面兩種異常的捕獲處理。

不過(guò)這兩個(gè)的共同點(diǎn)就是他們都返回 Image。

所以對(duì)于圖片的異常捕獲可以使用下面通用模板:

// Image image = Image(image: new CachedNetworkImageProvider('')); Image image = Image.network(''); final ImageStream stream = image.image.resolve(ImageConfiguration.empty); stream.addListener((_, __) {}, onError: (dynamic exception, StackTrace stackTrace) {//TODO error callback });

這里首先是獲得 Image,如果獲得的是 ImageProvider,只需要把 image.image 換為你的 ImageProvider 即可,當(dāng)然這個(gè)筆者沒測(cè)試,只是看源碼上面模板 image.image 的類型是 ImageProvider。

addListener 有兩個(gè)回調(diào),其中成功回調(diào)是必填的,有兩個(gè)參數(shù),因?yàn)檫@里不需要用到,因此第一個(gè)參數(shù)是一個(gè)下劃線,第二個(gè)參數(shù)是兩個(gè)下劃線。可能你會(huì)說(shuō)不需要用到,可不可以直接填 null。不行,這邊測(cè)試了,填 null 當(dāng)圖片加載成功時(shí)控制臺(tái)會(huì)拋異常。所以提供一個(gè)不需要任何實(shí)現(xiàn)的回調(diào)即可。

錯(cuò)誤回調(diào)是可選的,因?yàn)槲覀儽酒闹黝}就是要獲取錯(cuò)誤回調(diào),所以這里提供了實(shí)現(xiàn)。

針對(duì)我們上面的 3 個(gè)例子,我們看看通用模板是否可以全部捕獲。

1.一個(gè)圖片的 url

Widget _buildWidget() {Image image = Image.network('https://upload-images.jianshu.io/upload_images/5361063-e413832da0038304.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800');final ImageStream stream = image.image.resolve(ImageConfiguration.empty);stream.addListener((_,__){}, onError: (dynamic exception, StackTrace stackTrace) {print('enter onError start');print(exception);print(stackTrace);print('enter onError end');});return image; }

圖片加載成功。

2.不可訪問 url,如隨便一個(gè)字符串 test

Widget _buildWidget() {Image image = Image.network('test');final ImageStream stream = image.image.resolve(ImageConfiguration.empty);stream.addListener((_,__){}, onError: (dynamic exception, StackTrace stackTrace) {print('enter onError start');print(exception);print(stackTrace);print('enter onError end');});return image; }

控制臺(tái)輸出如下:

flutter: enter onError start flutter: Invalid argument(s): No host specified in URI file:///test flutter: #0 _HttpClient._openUrl (dart:_http/http_impl.dart:2121:9) #1 _HttpClient.getUrl (dart:_http/http_impl.dart:2056:48) #2 NetworkImage._loadAsync (package:flutter/src/painting/image_provider.dart:486:57) <asynchronous suspension> #3 NetworkImage.load (package:flutter/src/painting/image_provider.dart:471:14) #4 ImageProvider.resolve.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:267:86) #5 ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:143:20) #6 ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:267:63) #7 SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:38:29) #8 ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:265:30) #9 MyApp._buildWidget (package:my_flutter/main.dart:20:42) #10 MyApp.build (package:my_flutter/main.dart:12:18) #11 StatelessElement.build (package:flutter/<…> flutter: enter onError end

可以看到確實(shí)進(jìn)入錯(cuò)誤回調(diào)了。

3.可訪問非圖片 url,比如 http://mp.weixin.qq.com/mp/homepage?__biz=MzI3OTAyNzAwNg==&hid=5&sn=7e4598d8b00537fe2846f2e85d746b9a&scene=18#wechat_redirect

Widget _buildWidget() {Image image = Image.network('http://mp.weixin.qq.com/mp/homepage?__biz=MzI3OTAyNzAwNg==&hid=5&sn=7e4598d8b00537fe2846f2e85d746b9a&scene=18#wechat_redirect');final ImageStream stream = image.image.resolve(ImageConfiguration.empty);stream.addListener((_,__){}, onError: (dynamic exception, StackTrace stackTrace) {print('enter onError start');print(exception);print(stackTrace);print('enter onError end');});return image; }

控制臺(tái)輸出如下:

[VERBOSE-2:codec.cc(97)] Failed decoding image. Data is either invalid, or it is encoded using an unsupported format. flutter: enter onError start flutter: Exception: operation failed flutter: #0 NetworkImage._loadAsync (package:flutter/src/painting/image_provider.dart:498:12) <asynchronous suspension> #1 NetworkImage.load (package:flutter/src/painting/image_provider.dart:471:14) #2 ImageProvider.resolve.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:267:86) #3 ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:143:20) #4 ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:267:63) #5 SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:38:29) #6 ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:265:30) #7 MyApp._buildWidget (package:my_flutter/main.dart:20:42) #8 MyApp.build (package:my_flutter/main.dart:12:18) #9 StatelessElement.build (package:flutter/src/widgets/framework.dart:3774:28) #10 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15<…> flutter: enter onError end

可以看到確實(shí)進(jìn)入錯(cuò)誤回調(diào)了。

更多閱讀:

Flutter 入門系列博客
Flutter & Dart

最后來(lái)一個(gè)彩蛋表情包:

轉(zhuǎn)載于:https://www.cnblogs.com/nesger/p/10709079.html

總結(jié)

以上是生活随笔為你收集整理的Flutter 异常处理之图片篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。