一.简介
在开发ionic
应用程序中,我们难免会涉及到文件的下载,并且将下载的文件(可以是png
,pdf
,zip
等文件)保存到本地,时间一久,文件堆积过多,就需要对缓存进行清理以减少占用手机空间。我们先讲一下文件的保存,然后再讲清除缓存。
二.文件的保存
顺便提一下,关于文件的下载,有2篇文件讲得不错大家可以借鉴一下,前者是讲通过fileTransfer插件来进行文件的下载,后者通过XMLHttpRequest
来进行文件的下载(因为fileTransfer
已经过期,github上说可以使用XMLHttpRequest
),我这边也是使用后一篇文章介绍的方法来处理文件下载。
我们讲讲文件的保存,需要用到的插件:
cordova-plugin-file
如果需要打开下载之后的文件,可以使用:
cordova-plugin-file-opener2
上面两个插件file和file-opener2的安装方法参照ionic官网的文档即可。
这里需要注意一下,由于我使用的是ionic3进行开发,如今ionic4已经出来一段时间了。
安装完opener2
后,进行build android
就遇到了比较多的问题,我不太确定是不是这个插件的影响,但是在安装这个插件之前build android
是没有报错的:
1.安装opener2
之后,进行ionic cordova build android
,如果报错unable to merge dex,可以使用cordova clean android
,再使用ionic cordova build android
(我是直接cordova platform rm android
,然后cordova platform add android
,最后再ionic cordova build android
来解决问题的,如果上面不能解决的话,就试试我这种rm
平台的方法)。
2.安装opener2
之后,如果build android
报错‘Attribute meta-data#android.support.VERSION’的话,需要去到项目的platform-android-build.gradle
路径,在build.gradle
文件中加入以下代码,其中的‘25.3.1’
就是你报错中要支持的版本:
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '25.3.1'
}
}
}
}
保存文件前,先创建一个文件夹用来存放下载的文件,起名为myFile
:
checkDir(){
if(this.device.platform == null) {
return;
}
let that = this;
//获取路径
let path;
if(that.platform.is('ios')){//ios
path = that.file.cacheDirectory;
}else {
path = that.file.externalCacheDirectory;
}
that.file.checkDir(path,"myFile").then(isExist=>{
if(isExist){
console.log("---checkDir 文件夹已经存在----");
}else {
console.log("---文件夹不存在----");
//创建文件夹
that.file.createDir(path,"myFile",true).then(()=>{
console.log("---创建文件夹成功----");
}).catch(() => {
console.log("---创建文件夹失败----");
});
}
}).catch(() => {
console.log("---checkDir 失败----");
//创建文件夹
that.file.createDir(path,"myFile",true).then(()=>{
console.log("---创建文件夹成功----");
}).catch(() => {
console.log("---创建文件夹失败----");
});
});
}
先检查有没有这个文件夹,没有才创建;存放文件夹的位置放在了cache
里面。
保存并打开文件:
writeAndOpenFiles(url){
console.log("--writeAndopenFiles--");
let that = this;
//获取fileName
let fileName;
fileName = url.substring(url.lastIndexOf('/') + 1,url.length);
//获取路径
let path;
if(that.platform.is('ios')){//ios
path = that.file.cacheDirectory;
}else {
path = that.file.externalCacheDirectory;
}
path = path + "myFile/";
//第一次下载之后,需要先保存才能打开
that.file.writeFile(path, fileName,blob, {
replace: true
}).then(()=>{
console.log("--writeFile success--");
//open
let mimeType = that.getFileMimeType(fileName);
that.fileOpener.open(path + fileName, mimeType)
.then(() => {
console.log('打开成功');
})
.catch(() => {
console.log('打开失败');
});
}).catch((err=>{
console.log("--writeFile fail--");
}));
}
getFileMimeType(fileName: string): string {
let mimeType: string = '';
//获取文件的类型
let fileType = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length).toLowerCase();
switch (fileType) {
case 'txt':
mimeType = 'text/plain';
break;
case 'docx':
mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
break;
case 'doc':
mimeType = 'application/msword';
break;
case 'pptx':
mimeType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
break;
case 'ppt':
mimeType = 'application/vnd.ms-powerpoint';
break;
case 'xlsx':
mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
case 'xls':
mimeType = 'application/vnd.ms-excel';
break;
case 'zip':
mimeType = 'application/x-zip-compressed';
break;
case 'rar':
mimeType = 'application/octet-stream';
break;
case 'pdf':
mimeType = 'application/pdf';
break;
case 'jpg':
mimeType = 'image/jpeg';
break;
case 'png':
mimeType = 'image/png';
break;
default:
mimeType = 'application/' + fileType;
break;
}
return mimeType;
}
其中的url
是下载的文件地址,blob
是下载成功之后得到的文件数据,'myFile/'
是存放下载文件的位置。注意一点,file.writeFile
成功的话,success
和fail
的回调都会相应,不知道算不算file
插件的bug
。
三.清除缓存
清除缓存实际上就是清除下载的文件,对于我而言仅需清除cache
里面的文件即可。
清除之前,可以计算一下所占的缓存容量并且显示在app
上:
caculateCacheSize(){
let that = this;
//获取路径
let path;
if(that.platform.is('ios')){//ios
path = that.file.cacheDirectory;
}else {
path = that.file.externalCacheDirectory;
}
that.file.listDir(path,"myFile").then(entry=>{
console.log('---listDir成功---' + entry.length);
let totalSize = 0;
for(let i = 0;i < entry.length;i++){
entry[i].getMetadata(
(metadata)=>{
console.log("--metadata.size--" + metadata.size);
totalSize = totalSize + metadata.size;
if(i == entry.length - 1){
that.formatSize(totalSize);
}
},()=>{
})
}
}).catch(err => {
console.log('---listDir失败---' + err);
});
}
formatSize(size){
let tempSize = (parseFloat(size))/(1024*1024);
console.log("---tempSize---" + tempSize);
if(tempSize >= 0 && tempSize < 1024){//MB
tempSize = Math.floor(tempSize * 100)/100;
this.sizeStr = tempSize + "MB";
}else {//GB
tempSize = Math.floor(tempSize * 100)/100;
this.sizeStr = tempSize/1024 + "GB";
}
console.log("---sizeStr---" + this.sizeStr);
}
其中的this.sizeStr
就是占用的内存,这里只算了MB
和GB
,大家可以根据自身需求修改KB
等。
清除缓存:
clearCache(){
if(this.device.platform == null) {
this.methodsProvider.showToast("请在真实的手机设备上清除缓存");
return;
}
let that = this;
//获取路径
let path;
if(that.platform.is('ios')){//ios
path = that.file.cacheDirectory;
}else {
path = that.file.externalCacheDirectory;
}
that.file.checkDir(path,"myFile").then(isExist=>{
if(isExist){
console.log("---checkDir 文件夹已经存在----");
//移除文件夹及其里面的文件
that.file.removeRecursively(path,"myFile").then(removeResult=>{
that.methodsProvider.showToast("清除缓存成功");
}).catch(err => {
that.methodsProvider.showToast("清除缓存失败");
});
}else {
that.methodsProvider.showToast("清除缓存成功");
}
}).catch(() => {
console.log("---checkDir 失败----");
that.methodsProvider.showToast("清除缓存成功");
});
}
注意这里使用file.removeRecursively
是清除文件夹和文件夹里面的文件,文件夹里面有文件的话,就不要使用file.removeDir
,这个仅仅是删除文件夹,否者会报错。
四.总结
对于ionic
应用程序的清除缓存,想到的就是清除你已经下载到本地的文件,当然还有localStorage
的数据清除,如果还有其他的清除,请各位给我留言,大家共同进步。