Bevor ich zu Ihrer Frage komme, finden Sie hier eine kurze Erläuterung der beiden Speichertypen:
Zwischenspeicher
Dies ist ein app-spezifisches Verzeichnis im Dateisystem. In diesem Verzeichnis sollen temporäre Daten gespeichert werden, die Ihre Anwendung möglicherweise zwischen den Sitzungen aufbewahren muss, die jedoch möglicherweise nicht unbedingt für immer gespeichert werden müssen. Normalerweise greifen Sie mit auf dieses Verzeichnis zu Context.getCacheDir()
. Dies wird in Ihren App-Einstellungen als "Cache" angezeigt.
Dateien
Wie das Cache-Verzeichnis verfügt auch Ihre App über ein app-spezifisches Verzeichnis zum Speichern von Dateien. Dateien in diesem Verzeichnis bleiben bestehen, bis die App sie explizit löscht oder die App deinstalliert wird. Normalerweise greifen Sie mit auf dieses Verzeichnis zu Context.getFilesDir()
. Dies kann auf dem App-Infobildschirm als verschiedene Dinge angezeigt werden, aber in Ihrem Screenshot ist dies "USB-Speicherdaten".
HINWEIS: Wenn Sie explizit auf externen Medien (normalerweise SD-Karte) platzieren möchten, können Sie diese verwenden Context.getExternalFilesDir(String type)
.
Der Unterschied
Beide Verzeichnisse sind nur für Ihre Anwendung spezifisch (andere Apps haben keinen Zugriff). Einer der Unterschiede zwischen dem Cache- und dem Dateiverzeichnis besteht darin, dass das System zunächst Ressourcen aus Ihrem Cache-Verzeichnis freigibt, wenn der Speicherplatz knapp wird. Das System löscht keine Daten aus dem Dateiverzeichnis. Ein weiterer Unterschied besteht darin, dass das Cache-Verzeichnis normalerweise manuell über den App-Info-Bildschirm gelöscht werden kann. Das Dateiverzeichnis kann dies normalerweise auch, aber das Löschen des Dateiverzeichnisses löscht auch das Cache-Verzeichnis.
Welches benutze ich?
Dies hängt davon ab, wie wichtig diese Daten im Vergleich zur Lebensdauer Ihrer App sind. Wenn Sie nur Daten für eine Sitzung benötigen und Zweifel haben, dass Sie diese Daten jemals wieder verwenden müssen, verwenden Sie sie auch nicht. Behalten Sie es einfach im Speicher, bis Sie es nicht mehr benötigen. Wenn Sie Sie vermuten , werden die Daten zwischen mehreren Sitzungen wiederverwendet werden müssen, aber Sie nicht haben eine harte Kopie zu halten, verwenden Sie das Cache - Verzeichnis. Wenn Sie diese Daten haben müssen, egal was passiert, oder wenn es sich um ziemlich große Daten handelt, die dauerhaft gespeichert werden müssen, verwenden Sie das Dateiverzeichnis. Hier sind einige Beispiele, die mir einfallen:
- Cache - Eine kürzlich geöffnete E-Mail
- Speichern Sie die Daten nach dem Öffnen im Cache. Wenn der Benutzer diese E-Mail erneut lesen möchte, wird sie sofort geladen, anstatt das Netzwerk erneut zu verwenden, um dieselben Daten abzurufen. Ich muss das nicht für immer behalten, da der Benutzer schließlich mit der E-Mail fertig sein wird.
- Dateien - Ein Anhang, der aus einer E-Mail heruntergeladen wurde
- Dies ist eine Aktion des Benutzers, der sagt: "Ich möchte diese Daten behalten, damit ich sie jederzeit wieder aufrufen kann." Legen Sie es daher im Dateiverzeichnis ab, da ich diese Datei erst löschen möchte, wenn der Benutzer sie löschen möchte.
Wann sollte ich das Cache-Verzeichnis löschen?
Aus den Context.getCacheDir()
Javadocs:
Hinweis: Sie sollten sich nicht darauf verlassen, dass das System diese Dateien für Sie löscht. Sie sollten immer ein angemessenes Maximum haben, z. B. 1 MB, für den Speicherplatz, den Sie mit Cache-Dateien belegen, und diese Dateien bereinigen, wenn dieser Speicherplatz überschritten wird.
Es wird das Beispiel von 1 MB verwendet, aber das kann für Ihre App sinnvoll sein oder auch nicht. Unabhängig davon müssen Sie ein hartes Maximum festlegen. Der Grund dafür liegt einfach darin, eine verantwortungsvolle App zu entwerfen. Wann sollten Sie nachsehen? Ich würde empfehlen, jedes Mal zu überprüfen, wenn Sie etwas in das Cache-Verzeichnis stellen möchten. Hier ist ein sehr einfacher Cache-Manager:
public class CacheManager {
private static final long MAX_SIZE = 5242880L;
private CacheManager() {
}
public static void cacheData(Context context, byte[] data, String name) throws IOException {
File cacheDir = context.getCacheDir();
long size = getDirSize(cacheDir);
long newSize = data.length + size;
if (newSize > MAX_SIZE) {
cleanDir(cacheDir, newSize - MAX_SIZE);
}
File file = new File(cacheDir, name);
FileOutputStream os = new FileOutputStream(file);
try {
os.write(data);
}
finally {
os.flush();
os.close();
}
}
public static byte[] retrieveData(Context context, String name) throws IOException {
File cacheDir = context.getCacheDir();
File file = new File(cacheDir, name);
if (!file.exists()) {
return null;
}
byte[] data = new byte[(int) file.length()];
FileInputStream is = new FileInputStream(file);
try {
is.read(data);
}
finally {
is.close();
}
return data;
}
private static void cleanDir(File dir, long bytes) {
long bytesDeleted = 0;
File[] files = dir.listFiles();
for (File file : files) {
bytesDeleted += file.length();
file.delete();
if (bytesDeleted >= bytes) {
break;
}
}
}
private static long getDirSize(File dir) {
long size = 0;
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile()) {
size += file.length();
}
}
return size;
}
}
Dies kann natürlich eine teure Operation sein, daher sollten Sie planen, einen Hintergrund-Thread zwischenzuspeichern.
Dies kann auch so kompliziert sein, wie Sie es brauchen. In meinem Beispiel gehe ich davon aus, dass alle zwischengespeicherten Dateien im Stammverzeichnis des Cache-Verzeichnisses abgelegt sind, sodass ich nicht nach potenziellen Unterverzeichnissen suche. Die Routine zum Löschen von Dateien kann auch komplexer werden, z. B. das Löschen von Dateien nach dem ältesten Zugriffsdatum.
Wenn Sie sich für das Zwischenspeichern von Daten entscheiden, sollten Sie immer berücksichtigen, dass Ihre zwischengespeicherten Daten nicht mehr vorhanden sind. Stellen Sie immer eine Routine bereit, um Daten auf externe Weise abzurufen, wenn Ihr Cache sie nicht gespeichert hat. Überprüfen Sie auch immer Ihren Cache, bevor Sie Daten extern abrufen. Der Zweck des Caches besteht darin, die Netzwerkaktivität und die langen Prozesse zu reduzieren und eine reaktionsschnelle Benutzeroberfläche in Ihrer App bereitzustellen. Also benutze es verantwortungsbewusst :)