Nicht optimierte Downloads vermeiden

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

Die grundlegendste Methode zur Reduzierung der Downloads besteht darin, nur die Dateien herunterzuladen, die Sie wirklich benötigen. In Bezug auf die Daten bedeutet dies, REST APIs zu implementieren, mit denen Sie Abfragekriterien angeben können, die die zurückgegebenen Daten mithilfe von Parametern wie dem Zeitpunkt der letzten Aktualisierung begrenzen.

Ebenso empfiehlt es sich beim Herunterladen von Bildern, die Größe der Bilder serverseitig zu reduzieren, anstatt Bilder in voller Größe herunterzuladen, die auf dem Client verkleinert werden.

HTTP-Antworten im Cache speichern

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

Es ist wichtig, so aggressiv wie möglich im Cache zu speichern, um die Gesamtmenge der heruntergeladenen Daten zu reduzieren. Statische Ressourcen, einschließlich On-Demand-Downloads wie Bilder in Originalgröße, sollten immer 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 beim Caching keine veralteten Daten in der Anwendung angezeigt werden, verwenden Sie die entsprechenden HTTP-Statuscodes und -Header, z. B. die Header ETag und Last-Modified. So können Sie festlegen, wann der verknüpfte Inhalt aktualisiert werden soll. Beispiele:

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 mit OkHttp ein Cache-Verzeichnis und eine Cache-Größe für den Client konfigurieren, kann die Bibliothek das HTTP-Caching verwenden, 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 verarbeiten, sodass keine Netzwerkverbindung hergestellt werden muss. Bedingte im Cache gespeicherte Antworten können ihre Aktualität vom Server validieren, wodurch die mit dem Download verbundenen Bandbreitenkosten eliminiert werden. Nicht zwischengespeicherte Antworten werden für zukünftige Anfragen im Antwortcache gespeichert.

Mit Context.getExternalCacheDir() können Sie nicht vertrauliche Daten im nicht verwalteten externen Cache-Verzeichnis zwischenspeichern. Alternativ können Sie Daten mit Context.getCacheDir() im verwalteten, sicheren Anwendungscache zwischenspeichern. Dieser interne Cache kann geleert werden, wenn im System nur noch wenig Speicherplatz verfügbar ist.

Repository verwenden

Für einen ausgefeilteren Caching-Ansatz sollten Sie das Designmuster "Repository" in Betracht ziehen. Dazu muss eine benutzerdefinierte Klasse, ein sogenanntes Repository, erstellt werden, das eine API-Abstraktion für bestimmte Daten oder Ressourcen bietet. Das Repository kann seine Daten anfangs aus verschiedenen Quellen abrufen, z. B. von einem Remote-Webdienst. Bei nachfolgenden Aufrufen erhalten Aufrufer jedoch eine im Cache gespeicherte Version der Daten. Mit dieser Ebene der Indirektion können Sie eine robuste Caching-Strategie speziell für Ihre Anwendung bereitstellen. Weitere Informationen zur Verwendung des Repository-Musters in Ihrer Anwendung finden Sie im Leitfaden zur Anwendungsarchitektur.