Flutter 清除應(yīng)用緩存

清除應(yīng)用緩存是 APP 常用的功能之一。清除緩一般只有 2 個(gè)操作:

  • 獲取緩存大小
  • 清除緩存數(shù)據(jù)

本文通過(guò)實(shí)現(xiàn)一個(gè)緩存管理類,來(lái)操作應(yīng)用緩存。

定義緩存管理類

緩存管理類,是一個(gè)簡(jiǎn)單的緩存管理封裝,他通過(guò)幾個(gè)接口共 APP 組件使用。

該類需要使用到以下依賴:

首先建立緩存管理類,并規(guī)劃好一個(gè)大綱:

/// 緩存管理類
/// ./lib/utils/cache_util.dart
class CacheUtil {
  /// 獲取緩存大小
  static Future<int> total() async {}
  
  /// 清除緩存
  static Future<int> clear() async {}
  
  /// 遞歸緩存目錄,計(jì)算緩存大小
  static Future<int> _reduce() async {}
  
  /// 遞歸刪除緩存目錄和文件
  static Future<int> _delete() async {}
}

獲取緩存大小

獲取緩存大小,需要遞歸處理計(jì)算緩存目錄下的文件大小。

/// 獲取緩存大小
static Future<int> total() async {
  Directory tempDir = await getTemporaryDirectory();
  if (tempDir == null) return 0;
  int total = await _reduce(tempDir);
  return total;
}

遞歸計(jì)算緩存目錄:

/// 遞歸緩存目錄,計(jì)算緩存大小
static Future<int> _reduce(final FileSystemEntity file) async {
  /// 如果是一個(gè)文件,則直接返回文件大小
  if (file is File) {
    int length = await file.length();
    return length;
  }

  /// 如果是目錄,則遍歷目錄并累計(jì)大小
  if (file is Directory) {
    final List<FileSystemEntity> children = file.listSync();

    int total = 0;

    if (children != null && children.isNotEmpty)
      for (final FileSystemEntity child in children)
        total += await _reduce(child);

    return total;
  }

  return 0;
}

清除緩存

和遞歸獲取緩存目錄下的文件大小類似,清除緩存就是遍歷刪除緩存目錄下的文件:

/// 清除緩存
static Future<void> clear() async {
  Directory tempDir = await getTemporaryDirectory();
  if (tempDir == null) return;
  await _delete(tempDir);
}

遞歸清除緩存目錄:

/// 遞歸刪除緩存目錄和文件
static Future<void> _delete(FileSystemEntity file) async {
  if (file is Directory) {
    final List<FileSystemEntity> children = file.listSync();
    for (final FileSystemEntity child in children) {
      await _delete(child);
    }
  } else {
    await file.delete();
  }
}

完整代碼

完整代碼如下:

import 'dart:io';
import 'package:path_provider/path_provider.dart';

/// 緩存管理類
/// ./lib/utils/cache_util.dart
class CacheUtil {
  /// 獲取緩存大小
  static Future<int> total() async {
    Directory tempDir = await getTemporaryDirectory();
    if (tempDir == null) return 0;
    int total = await _reduce(tempDir);
    return total;
  }

  /// 清除緩存
  static Future<void> clear() async {
    Directory tempDir = await getTemporaryDirectory();
    if (tempDir == null) return;
    await _delete(tempDir);
  }

  /// 遞歸緩存目錄,計(jì)算緩存大小
  static Future<int> _reduce(final FileSystemEntity file) async {
    /// 如果是一個(gè)文件,則直接返回文件大小
    if (file is File) {
      int length = await file.length();
      return length;
    }

    /// 如果是目錄,則遍歷目錄并累計(jì)大小
    if (file is Directory) {
      final List<FileSystemEntity> children = file.listSync();

      int total = 0;

      if (children != null && children.isNotEmpty)
        for (final FileSystemEntity child in children)
          total += await _reduce(child);

      return total;
    }

    return 0;
  }

  /// 遞歸刪除緩存目錄和文件
  static Future<void> _delete(FileSystemEntity file) async {
    if (file is Directory) {
      final List<FileSystemEntity> children = file.listSync();
      for (final FileSystemEntity child in children) {
        await _delete(child);
      }
    } else {
      await file.delete();
    }
  }
}

應(yīng)用實(shí)戰(zhàn)

實(shí)戰(zhàn)中,我們添加 filesize 依賴用來(lái)友好顯示文件尺寸。使用 ValueNotifierValueListenableBuilder 更新界面。實(shí)現(xiàn)過(guò)程如下:

  • 定義一個(gè) cacheSizeValueNotifier<int> cacheSize = ValueNotifier(0);
  • 定義一個(gè) initCache 異步方法,用來(lái)刷新緩存,在 initStat 和 清除緩存 時(shí)調(diào)用,已實(shí)現(xiàn)實(shí)時(shí)刷新。
  • 定義一個(gè) 清除緩存 的方法,用來(lái)調(diào)用清除緩存和刷新緩存。
Simulator Screen Shot - iPhone 11 - 2021-03-27 at 13.06.05.png

緩存展示組件

ValueListenableBuilder(
  valueListenable: cacheSize,
  builder: (BuildContext context, int size, Widget _) {
    return Tile(
      title: Text('本地緩存'),
      titleSub: Text('點(diǎn)擊清除緩存,但不會(huì)清除已下載的歌曲'),
      detail: size != null && size > 0 ? filesize(size) : '',
      action: SizedBox(width: 16),
      onPressed: handleClearCache,
    );
  },
)

初始化緩存方法

Future<void> initCache() async {
  /// 獲取緩存大小
  int size = await CacheUtil.total();
  /// 復(fù)制變量
  cacheSize.value = size ?? 0;
}

清除緩存方法

Future<void> handleClearCache() async {
  try {
    if (cacheSize.value <= 0) throw '沒(méi)有緩存可清理';
    
    /// 給予適當(dāng)?shù)奶崾?    /// bool confirm = await showDialog();
    /// if (confirm != true) return;

    /// 執(zhí)行清除緩存
    await CacheUtil.clear();

    /// 更新緩存
    await initCache();

    AppUtil.showToast('緩存清除成功');
  } catch (e) {
    AppUtil.showToast(e);
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容