Flutter cached_network_image圖片緩存異常/加載失敗優化

很多應用都會這麼操作,把一些圖像進行緩存可以提升用戶體驗,也能減輕資源浪費,這裏以cached_network_image爲例。它可以將網絡圖像進行本地緩存,在需要的時候直接加載,提供了兩個使用方法:

CachedNetworkImage(
        imageUrl: "http://via.placeholder.com/350x150",
        placeholder: (context, url) => CircularProgressIndicator(),
        errorWidget: (context, url, error) => Icon(Icons.error),
     ),

CachedNetworkImage可以直接使用,也可以通過ImageProvider使用。

Image(image: CachedNetworkImageProvider(url))

如果您想同時擁有佔位符功能和要在另一個窗口小部件中使用imageprovider,則可以提供imageBuilder:

CachedNetworkImage(
  imageUrl: "http://via.placeholder.com/200x150",
  imageBuilder: (context, imageProvider) => Container(
    decoration: BoxDecoration(
      image: DecorationImage(
          image: imageProvider,
          fit: BoxFit.cover,
          colorFilter:
              ColorFilter.mode(Colors.red, BlendMode.colorBurn)),
    ),
  ),
  placeholder: (context, url) => CircularProgressIndicator(),
  errorWidget: (context, url, error) => Icon(Icons.error),
),

圖像加載失敗:404,403等

如果你使用了CachedNetworkImageProvider的話,錯誤信息如:

I/flutter (21047): CacheManager: Failed to download file from https://pic.xx.com/28000.jpg with error:
I/flutter (21047): SocketException: Failed host lookup: 'pic.xx.com' (OS Error: No address associated with hostname, errno = 7)
I/flutter (21047): CacheManager: Failed to download file from https://pic.xx.com/23730.jpg with error:
I/flutter (21047): SocketException: Failed host lookup: 'pic.aotorun.com' (OS Error: No address associated with hostname, errno = 7)
I/flutter (21047): CacheManager: Failed to download file from  with error:
I/flutter (21047): Invalid argument(s): No host specified in URI 
I/flutter (21047): CacheManager: Failed to download file from  with error:
I/flutter (21047): Invalid argument(s): No host specified in URI 
I/flutter (21047): CacheManager: Failed to download file from https://i1.xx.com/623946/4c71965fac192ebe.jpg with error:
I/flutter (21047): HttpException: No valid statuscode. Statuscode was 404
I/flutter (21047): CacheManager: Failed to download file from https://i1.xx.com/623946/4c71965fac192ebe.jpg with error:
I/flutter (21047): HttpException: No valid statuscode. Statuscode was 404

如果是CachedNetworkImage則如下:

I/flutter (21047): Path:

I/flutter (21047): /data/user/0/com.example.xx/cache/libCachedImageData/68b03f20-1fa4-11ea-9f10-49083fd8fc8f.jpeg
I/flutter (21047): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (21047): Another exception was thrown: Exception: Could not instantiate image codec.

 

如何解決?

從文檔提供的資料來看,沒有對應的解決方案,在issues中我看到大量提出該問題的疑惑,都是在問如何解決的,但目前來看也沒有相應的解決方案。其中看到最新的維護人員的回覆:

I'd expect that the user of this library makes sure that the url is completely valid,
==>我希望該庫的用戶確保網址完全有效,

這是理想的狀態,但如果圖片資源涉及到第三方存儲,這就難免出現意外。請求出錯的情況包括但不限於:

  • 404,圖片不存在
  • 403,無權限訪問
  • 無效圖片資源,比如佔位符並不是有效圖像
  • 網絡不通
  • ……

這樣一看,處理起來確實麻煩,因爲有時間差,即使能從返回信息來處理,但回調超時體驗上就會造成體驗不好。如果是能有效控制維護的數據和API當然可以像官方所說的一樣,確保圖片資源有效,不管是增刪還是301跳轉等都好處理,但這不現實。

問題還沒解決,有最新進展會繼續更……

解決方法一:

 precacheImage(
        CachedNetworkImageProvider(image),
        context, onError: (e, stackTrace) {
      print(('Image failed to load with error:$e'));
      setState(() {
        imgCheck = false;
      });
    });

使用precacheImage方法進行圖片預加載,該方法有一個回調onError,它會讀取緩存中是否存在err,如果存在,你就可以做點什麼了?經測試該方法能解決圖像404和網絡異常導致的問題。但對於圖片URL存在真實有效,卻不是一個有效圖片這個沒法判斷。

繼續。。。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章