Flutter 获取应用缓存需要借助于path_provider插件。 path_provider 是一个用于查找文件系统上常用位置的Flutter插件。用来获取 Android 和 iOS 的缓存文件夹,然后再根据文件循环计算出缓存文件的大小。
以下是官方解释:
A Flutter plugin for finding commonly used locations on the filesystem. Supports iOS and Android.
目前可用最高版本为2.0.5。版本来源参考:path_provider 2.0.5
方法介绍
path_provider
中获取文件夹的方法:
1、getTemporaryDirectory()
///< 在iOS上,对应NSTemporaryDirectory()
;在Android上,对应getCacheDir
。
2、getApplicationDocumentsDirectory()
///< 在iOS上,对应NSDocumentsDirectory
;在Android上,对应AppData
目录。
3、getExternalStorageDirectory()
///< 在iOS上,抛出异常,在Android上,对应getExternalStorageDirectory
。
以下是源码注释:
/// Path to the temporary directory on the device.
///
/// Files in this directory may be cleared at any time. This does *not* return
/// a new temporary directory. Instead, the caller is responsible for creating
/// (and cleaning up) files or directories within this directory. This
/// directory is scoped to the calling application.
///
/// On iOS, this uses the `NSCachesDirectory` API.
///
/// On Android, this uses the `getCacheDir` API on the context.
Future<Directory> getTemporaryDirectory() async {
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
final String path = await _channel.invokeMethod('getTemporaryDirectory');
if (path == null) {
return null;
}
return Directory(path);
}
/// Path to a directory where the application may place files that are private
/// to the application and will only be cleared when the application itself
/// is deleted.
///
/// On iOS, this uses the `NSDocumentsDirectory` API.
///
/// On Android, this returns the AppData directory.
Future<Directory> getApplicationDocumentsDirectory() async {
final String path =
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
await _channel.invokeMethod('getApplicationDocumentsDirectory');
if (path == null) {
return null;
}
return Directory(path);
}
/// Path to a directory where the application may access top level storage.
/// The current operating system should be determined before issuing this
/// function call, as this functionality is only available on Android.
///
/// On iOS, this function throws an UnsupportedError as it is not possible
/// to access outside the app's sandbox.
///
/// On Android this returns getExternalStorageDirectory.
Future<Directory> getExternalStorageDirectory() async {
if (Platform.isIOS)
throw UnsupportedError("Functionality not available on iOS");
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
final String path = await _channel.invokeMethod('getStorageDirectory');
if (path == null) {
return null;
}
return Directory(path);
}
使用方法
1、pubspec.yaml文件下添加依赖库:path_provider: ^1.6.8。并执行flutter packages get操作,若出现问题,可适当降低依赖版本。
# 添加文件依赖
path_provider: ^1.6.8
2、导入头文件
import 'package:path_provider/path_provider.dart';
import 'dart:io';
页面初始化时循环获得缓存大小
double cache = 0.0;
void initState() {
getSize();
super.initState();
}
getSize() async {
final _tempDir = await getTemporaryDirectory();
double _cache = await Utils.getTotalSizeOfFilesInDir(_tempDir);
setState(() {
cache = _cache;
});
}
ClickItem(
title: '清除缓存',
content: Utils.renderSize(cache),
onTap: () async {
print('清除');
try {
final _tempDir = await getTemporaryDirectory();
EasyLoading.show(status: '清除中');
await Utils.requestPermission(_tempDir);
EasyLoading.dismiss();
EasyLoading.showSuccess('清除成功');
getSize();
} catch (err) {
EasyLoading.dismiss();
EasyLoading.showError('清除失败');
}
},
),
Utils中的方法
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:permission_handler/permission_handler.dart';
static Future<Null> requestPermission(FileSystemEntity file) async {
PermissionStatus status = await Permission.storage.status;
await delDir(file);
}
static Future<Null> delDir(FileSystemEntity file) async {
if (file is Directory && file.existsSync()) {
print(file.path);
final List<FileSystemEntity> children =
file.listSync(recursive: true, followLinks: true);
for (final FileSystemEntity child in children) {
await delDir(child);
}
}
try {
if (file.existsSync()) {
await file.delete(recursive: true);
}
} catch (err) {
print(err);
}
}
//循环获取缓存大小
static Future getTotalSizeOfFilesInDir(final FileSystemEntity file) async {
// File
if (file is File && file.existsSync()) {
int length = await file.length();
return double.parse(length.toString());
}
if (file is Directory && file.existsSync()) {
List children = file.listSync();
double total = 0;
if (children.length > 0)
for (final FileSystemEntity child in children)
total += await getTotalSizeOfFilesInDir(child);
return total;
}
return 0;
}
//格式化文件大小
static String renderSize(value) {
if (value == null) {
return '0.0';
}
List<String> unitArr = []
..add('B')
..add('K')
..add('M')
..add('G');
int index = 0;
while (value > 1024) {
index++;
value = value / 1024;
}
String size = value.toStringAsFixed(2);
return size + unitArr[index];
}