Nicht optimierte Downloads vermeiden

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

Die grundlegendste Möglichkeit, die Anzahl der Downloads zu reduzieren, besteht darin, nur das herunterzuladen, was Sie benötigen. In Bezug auf Daten bedeutet das, REST APIs zu implementieren, mit denen Sie Abfragekriterien angeben können, die die zurückgegebenen Daten mithilfe von Parametern wie dem Zeitpunkt Ihrer letzten Aktualisierung einschränken.

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

HTTP-Antworten im Cache speichern

Eine weitere wichtige Technik besteht darin, das Herunterladen doppelter Daten zu vermeiden. Sie können die Wahrscheinlichkeit, dass dieselben Daten wiederholt heruntergeladen werden, durch Caching verringern. Wenn Sie die Daten und Ressourcen Ihrer App im Cache speichern, erstellen Sie eine lokale Kopie von den 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 Gesamt menge der heruntergeladenen Daten zu reduzieren. Speichern Sie statische Ressourcen, einschließlich On‑Demand-Downloads wie Bilder in voller Größe, so lange wie möglich im Cache. 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 keine veralteten Daten in Ihrer App angezeigt werden, verwenden Sie die entsprechenden HTTP-Statuscodes und ‑Header, z. B. die ETag und Last-Modified Header. So können Sie festlegen, wann die zugehörigen Inhalte aktualisiert werden sollen. Dazu ein paar 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 OkHttp verwenden, können Sie beispielsweise ein Cache-Verzeichnis und eine Cache-Größe für den Client konfigurieren, damit die Bibliothek HTTP-Caching verwendet, 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, ohne eine Netzwerkverbindung öffnen zu müssen. Bedingt im Cache gespeicherte Antworten können ihre Aktualität vom Server validieren lassen, wodurch die Bandbreitenkosten für den Download entfallen. Nicht im Cache gespeicherte Antworten werden für zukünftige Anfragen im Antwortcache gespeichert.

Sie können nicht vertrauliche Daten im nicht verwalteten externen Cache-Verzeichnis mit using Context.getExternalCacheDir() im Cache speichern. Alternativ können Sie Daten im verwalteten, sicheren Anwendungscache mit using Context.getCacheDir() im Cache speichern. Beachten Sie, dass dieser interne Cache möglicherweise geleert wird, wenn der verfügbare Speicherplatz auf dem System knapp wird.

Repository verwenden

Für einen anspruchsvolleren Ansatz für das Caching können Sie das Repository-Entwurfsmuster verwenden. Dabei wird eine benutzerdefinierte Klasse erstellt, die als Repository bezeichnet wird und eine API-Abstraktion für bestimmte Daten oder Ressourcen bietet. Das Repository ruft seine Daten möglicherweise zunächst aus verschiedenen Quellen ab, z. B. von einem Remote-Webdienst, stellt Aufrufern aber bei nachfolgenden Aufrufen eine im Cache gespeicherte Version der Daten zur Verfügung. Diese Ebene der Indirektion ermöglicht es Ihnen, eine robuste Caching-Strategie zu entwickeln, die speziell auf Ihre App zugeschnitten ist. Weitere Informationen zur Verwendung des Repository-Musters in Ihrer App finden Sie im Leitfaden zur App- Architektur.