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

Flutter圖片緩存管理ImageCache原理分析

 更新時間:2022年12月12日 15:13:14   作者:WeninerIo  
這篇文章主要為大家介紹了Flutter圖片緩存管理ImageCache原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

設(shè)計(jì): 嗯? 這個圖片點(diǎn)擊跳轉(zhuǎn)進(jìn)詳情再返回圖片怎么變白閃一下呢?
產(chǎn)品: 是啊是啊! 一定是個bug
開發(fā): 囧囧囧

在開發(fā)過程中, 也許你也遇到過這樣一個場景. 進(jìn)入一個頁面后,前一個頁面的圖片都會閃白一下. 或者在列表中,加載很多列表項(xiàng)后,之前列表中的圖片都需要重新加載.你有沒有想過這一切的原因是什么呢?

沒錯! 它就是我們今天介紹的主人公 --- ImageCache

可能有些人對ImageCache還有些陌生, 我們在之前的章節(jié)有說過啟動流程時Flutter runApp到渲染上屏,有介紹過其中PaintingBinding這個mixin類.帶著探索的心我們先去看看PaintingBinding都做了 一些什么操作呢?

PaintingBinding

PaintingBinding在構(gòu)造函數(shù)中,除了構(gòu)建自身的實(shí)例.同時也構(gòu)建了圖片緩存的管理實(shí)例.也包括了著色器預(yù)熱.

{
    _instance = this;
    // 創(chuàng)建了圖片緩存管理
    _imageCache = createImageCache();
    shaderWarmUp?.execute();
}

著色器預(yù)熱可能大部分人都沒有接觸過,我們只需要知道通過著色器預(yù)熱,可以提高首次編譯的速度即可.有興趣可以看一下這篇文章著色器預(yù)熱; 我們現(xiàn)在把目光重新聚焦到今天的主題, 也就是createImageCache()這里.可以看到它直接返回了一個ImageCache的對象. 這里我們暫且不談ImageCache, 再去看看在PaintingBinding有沒有和ImageCache相關(guān)的一些代碼吧.

  @override
  void evict(String asset) {
    // 調(diào)用了rootBundle.evict(asset);
    // 也就是從緩存中移除這個key的資源
    super.evict(asset);
    // 清除所有已顯示和不再用到的圖片緩存
    imageCache.clear();
    // 清除所有實(shí)時引用的圖片緩存
    imageCache.clearLiveImages();
  }

  @override
  void handleMemoryPressure() {
    // rootBundle.clear();
    // 當(dāng)操作系統(tǒng)通知應(yīng)用程序內(nèi)存壓力情況時調(diào)用。
    // 清除所有的圖片資源
    super.handleMemoryPressure();
    imageCache.clear();
  }

可以看到, 基本上所有的引用都避不開內(nèi)存問題. 也就是文章開頭出現(xiàn)的bug. 那么,為什么會出現(xiàn)閃白呢? 有多種可能,有可能是系統(tǒng)感受到了內(nèi)存壓力調(diào)用了handleMemoryPressure() 方法,清除了圖片緩存,或者在ImageCache中,達(dá)到了最大緩存,因此內(nèi)部根據(jù)least-recently-used的原則回收了圖片緩存.所以回頭再看的時候,圖片又重新加載了一遍.自然發(fā)生了閃白現(xiàn)象. 既然知道了原因,那么解決問題的方法:

  • 減少圖片緩存
  • 增大圖片緩存的閥值,讓系統(tǒng)感覺到壓力的閥值提升 我們來分別分析一下兩者的可行性

減少圖片緩存

如果要減少圖片緩存, 我們要知道圖片的內(nèi)存是怎么計(jì)算的? 圖片內(nèi)存=分辨率*每個像素點(diǎn)大小 減少的方法也就出來了:

  • 減少分辨率
    也就是降低采樣率.flutter中即cacheHeight和cacheWidth
  • 減少像素點(diǎn)大小
    這里也就是像素點(diǎn)的格式,ALPHA_8、RGB_565、ARGB_4444、ARGB_8888、RGBA_F16這些

增大閥值

這里需要去看一下ImageCache中.我們推斷一下,什么情況下一個緩存池會達(dá)到閥值呢? 那一定是有新圖片插入,所以總量才會提升才會夠到閥值的門檻.我們找一下有沒有相關(guān)的方法. 嗯哼~ 果然有一個_checkCacheSize

{
    ...
    // 只要當(dāng)前的內(nèi)存超標(biāo)就會一直執(zhí)行下去
    while (_currentSizeBytes > _maximumSizeBytes || _cache.length > _maximumSize) {
      // 根據(jù)least-recently-used這個邏輯去依次清除圖片緩存
      final Object key = _cache.keys.first;
      final _CachedImage image = _cache[key]!;
      _currentSizeBytes -= image.sizeBytes!;
      image.dispose();
      _cache.remove(key);
    }
    ...
}

說明我們閥值取決于_maximumSizeBytes和_maximumSize, 一個負(fù)責(zé)最大緩存圖片內(nèi)存,一個負(fù)責(zé)最大緩存圖片數(shù). 也就是說我們更新這兩個指就可以改變圖片內(nèi)存的閥值.從而減少內(nèi)存回收的頻率.

思考

很多問題的發(fā)生實(shí)際上源碼中都有些提示, 帶著問題去看收獲的遠(yuǎn)遠(yuǎn)比單獨(dú)閱讀源碼要有收獲的多.
這里是weniner,一個在奮斗的flutter. 有些收獲的話,不妨點(diǎn)個關(guān)注哦!

以上就是Flutter圖片緩存管理ImageCache原理分析的詳細(xì)內(nèi)容,更多關(guān)于Flutter ImageCache的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

榆树市| 龙门县| 二连浩特市| 武功县| 鄱阳县| 灌阳县| 全椒县| 台东市| 安化县| 桂平市| 嵊州市| 衡南县| 库尔勒市| 五华县| 临洮县| 宜昌市| 凌云县| 伊川县| 广昌县| 堆龙德庆县| 杭州市| 西乌珠穆沁旗| 贞丰县| 景德镇市| 上高县| 西盟| 镇巴县| 河间市| 灵宝市| 房产| 营山县| 石台县| 嘉峪关市| 拉萨市| 兴山县| 故城县| 恩平市| 琼中| 湖口县| 潜江市| 凭祥市|