一.簡(jiǎn)介
在開發(fā)ionic應(yīng)用程序中,我們難免會(huì)涉及到文件的下載,并且將下載的文件(可以是png,pdf,zip等文件)保存到本地,時(shí)間一久,文件堆積過多,就需要對(duì)緩存進(jìn)行清理以減少占用手機(jī)空間。我們先講一下文件的保存,然后再講清除緩存。
二.文件的保存
順便提一下,關(guān)于文件的下載,有2篇文件講得不錯(cuò)大家可以借鑒一下,前者是講通過fileTransfer插件來進(jìn)行文件的下載,后者通過XMLHttpRequest來進(jìn)行文件的下載(因?yàn)?code>fileTransfer已經(jīng)過期,github上說可以使用XMLHttpRequest),我這邊也是使用后一篇文章介紹的方法來處理文件下載。
我們講講文件的保存,需要用到的插件:
cordova-plugin-file
如果需要打開下載之后的文件,可以使用:
cordova-plugin-file-opener2
上面兩個(gè)插件file和file-opener2的安裝方法參照ionic官網(wǎng)的文檔即可。
這里需要注意一下,由于我使用的是ionic3進(jìn)行開發(fā),如今ionic4已經(jīng)出來一段時(shí)間了。
安裝完opener2后,進(jìn)行build android就遇到了比較多的問題,我不太確定是不是這個(gè)插件的影響,但是在安裝這個(gè)插件之前build android是沒有報(bào)錯(cuò)的:
1.安裝opener2之后,進(jìn)行ionic cordova build android,如果報(bào)錯(cuò)unable to merge dex,可以使用cordova clean android,再使用ionic cordova build android(我是直接cordova platform rm android,然后cordova platform add android,最后再ionic cordova build android來解決問題的,如果上面不能解決的話,就試試我這種rm平臺(tái)的方法)。

2.安裝opener2之后,如果build android報(bào)錯(cuò)‘Attribute meta-data#android.support.VERSION’的話,需要去到項(xiàng)目的platform-android-build.gradle路徑,在build.gradle文件中加入以下代碼,其中的‘25.3.1’就是你報(bào)錯(cuò)中要支持的版本:

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'
}
}
}
}
保存文件前,先創(chuàng)建一個(gè)文件夾用來存放下載的文件,起名為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 文件夾已經(jīng)存在----");
}else {
console.log("---文件夾不存在----");
//創(chuàng)建文件夾
that.file.createDir(path,"myFile",true).then(()=>{
console.log("---創(chuàng)建文件夾成功----");
}).catch(() => {
console.log("---創(chuàng)建文件夾失敗----");
});
}
}).catch(() => {
console.log("---checkDir 失敗----");
//創(chuàng)建文件夾
that.file.createDir(path,"myFile",true).then(()=>{
console.log("---創(chuàng)建文件夾成功----");
}).catch(() => {
console.log("---創(chuàng)建文件夾失敗----");
});
});
}
先檢查有沒有這個(gè)文件夾,沒有才創(chuàng)建;存放文件夾的位置放在了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是下載成功之后得到的文件數(shù)據(jù),'myFile/'是存放下載文件的位置。注意一點(diǎn),file.writeFile成功的話,success和fail的回調(diào)都會(huì)相應(yīng),不知道算不算file插件的bug。
三.清除緩存
清除緩存實(shí)際上就是清除下載的文件,對(duì)于我而言僅需清除cache里面的文件即可。
清除之前,可以計(jì)算一下所占的緩存容量并且顯示在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就是占用的內(nèi)存,這里只算了MB和GB,大家可以根據(jù)自身需求修改KB等。
清除緩存:
clearCache(){
if(this.device.platform == null) {
this.methodsProvider.showToast("請(qǐng)?jiān)谡鎸?shí)的手機(jī)設(shè)備上清除緩存");
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 文件夾已經(jīng)存在----");
//移除文件夾及其里面的文件
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,這個(gè)僅僅是刪除文件夾,否者會(huì)報(bào)錯(cuò)。
四.總結(jié)
對(duì)于ionic應(yīng)用程序的清除緩存,想到的就是清除你已經(jīng)下載到本地的文件,當(dāng)然還有localStorage的數(shù)據(jù)清除,如果還有其他的清除,請(qǐng)各位給我留言,大家共同進(jìn)步。