Nicht optimierte Downloads vermeiden

Einige Nutzer Ihrer App haben nur zeitweise Zugriff auf das Internet oder es gibt Beschränkungen für die Menge an Informationen, die sie auf ihre Geräte herunterladen können. Sie können Nutzer dazu anregen, häufiger mit Ihrer App zu interagieren, indem Sie die Menge der Daten reduzieren, die Ihre App herunterladen muss.

Die einfachste Möglichkeit, die Anzahl der Downloads zu reduzieren, besteht darin, nur das herunterzuladen, was Sie benötigen. In Bezug auf Daten bedeutet das, dass Sie REST APIs implementieren müssen, mit denen Sie Abfragekriterien angeben können, um die zurückgegebenen Daten mithilfe von Parametern wie dem Zeitpunkt Ihres letzten Updates einzuschränken.

Auch beim Herunterladen von Bildern empfiehlt es sich, die Größe der Bilder serverseitig zu verringern, anstatt Bilder in voller Größe herunterzuladen und sie dann auf dem Client zu verkleinern.

HTTP-Antworten im Cache speichern

Eine weitere wichtige Methode ist, das Herunterladen doppelter Daten zu vermeiden. Durch Caching können Sie die Wahrscheinlichkeit verringern, dass dieselben Daten wiederholt heruntergeladen werden. Durch das Cachen der Daten und Ressourcen Ihrer App erstellen Sie eine lokale Kopie der Informationen, auf die Ihre App verweisen muss. Wenn Ihre App innerhalb kurzer Zeit mehrmals auf dieselben Informationen zugreifen muss, müssen Sie sie nur einmal in den Cache herunterladen.

Es ist wichtig, so aggressiv wie möglich zu cachen, um die Gesamtmenge der heruntergeladenen Daten zu reduzieren. Statische Ressourcen, einschließlich On-Demand-Downloads wie Bilder in voller Größe, sollten so lange wie möglich im Cache gespeichert werden. On-Demand-Ressourcen sollten separat gespeichert werden, damit Sie den On-Demand-Cache regelmäßig leeren können, um seine Größe zu verwalten.

Damit durch das Caching in Ihrer App keine veralteten Daten angezeigt werden, verwenden Sie die entsprechenden HTTP-Statuscodes und ‑Header, z. B. die Header ETag und Last-Modified. So können Sie festlegen, wann die zugehörigen Inhalte aktualisiert werden sollen. Beispiel:

Kotlin

// url represents the website containing the content to place into the cache.
val conn: HttpsURLConnection = url.openConnection() as HttpsURLConnection
val currentTime: Long = System.currentTimeMillis()
val lastModified: Long = conn.getHeaderFieldDate("Last-Modified", currentTime)

// lastUpdateTime represents when the cache was last updated.
if (lastModified < lastUpdateTime) {
    // Skip update
} else {
    // Parse update
    lastUpdateTime = lastModified
}

Java

// url represents the website containing the content to place into the cache.
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
long currentTime = System.currentTimeMillis();
long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);

// lastUpdateTime represents when the cache was last updated.
if (lastModified < lastUpdateTime) {
    // Skip update
} else {
    // Parse update
    lastUpdateTime = lastModified;
}

Sie können einige Netzwerkbibliotheken so konfigurieren, dass diese Statuscodes und Header automatisch berücksichtigt werden. Wenn Sie beispielsweise OkHttp verwenden, können Sie durch Konfigurieren eines Cacheverzeichnisses und einer Cachegröße für den Client die Verwendung von HTTP-Caching durch die Bibliothek aktivieren, wie im folgenden Codebeispiel gezeigt:

Kotlin

val cacheDir = Context.getCacheDir()
val cacheSize = 10L * 1024L * 1024L // 10 MiB
val client: OkHttpClient = OkHttpClient.Builder()
    .cache(Cache(cacheDir, cacheSize))
    .build()

Java

File cacheDir = Context.getCacheDir();
long cacheSize = 10L * 1024L * 1024L; // 10 MiB
OkHttpClient client = new OkHttpClient.Builder()
    .cache(new Cache(cacheDir, cacheSize))
    .build();

Wenn der Cache konfiguriert ist, können Sie vollständig im Cache gespeicherte HTTP-Anfragen direkt aus dem lokalen Speicher bereitstellen. Eine Netzwerkverbindung muss dann nicht geöffnet werden. Bei bedingt im Cache gespeicherten Antworten kann die Aktualität vom Server validiert werden. So werden die mit dem Download verbundenen Bandbreitenkosten vermieden. Nicht im Cache gespeicherte Antworten werden für zukünftige Anfragen im Antwortcache gespeichert.

Sie können nicht sensible Daten im nicht verwalteten externen Cacheverzeichnis mit Context.getExternalCacheDir() zwischenspeichern. Alternativ können Sie Daten im verwalteten, sicheren Anwendungs-Cache mit Context.getCacheDir() speichern. Beachten Sie, dass dieser interne Cache geleert werden kann, wenn das System nur noch wenig verfügbaren Speicherplatz hat.

Repository verwenden

Wenn Sie einen komplexeren Ansatz für das Caching benötigen, sollten Sie das Repository-Entwurfsmuster in Betracht ziehen. Dazu müssen Sie eine benutzerdefinierte Klasse erstellen, die als Repository bezeichnet wird und eine API-Abstraktion für bestimmte Daten oder Ressourcen bereitstellt. Das Repository ruft seine Daten möglicherweise anfangs aus verschiedenen Quellen ab, z. B. einem Remote-Webdienst, stellt Aufrufern bei nachfolgenden Aufrufen jedoch eine im Cache gespeicherte Version der Daten zur Verfügung. Diese Indirektionsebene ermöglicht es Ihnen, eine robuste Caching-Strategie zu implementieren, die speziell auf Ihre App zugeschnitten ist. Weitere Informationen zur Verwendung des Repository-Musters in Ihrer App finden Sie im Leitfaden zur App-Architektur.