Niektórzy użytkownicy Twojej aplikacji mają ograniczony dostęp do internetu lub mają ograniczoną ilość informacji, które mogą pobrać na swoje urządzenia. Możesz zachęcić użytkowników do częstszego korzystania z aplikacji, zmniejszając ilość danych, które musi ona pobrać.
Najprostszym sposobem na ograniczenie liczby pobrań jest pobieranie tylko tego, czego potrzebujesz. W przypadku danych oznacza to implementację interfejsów API REST, które umożliwiają określenie kryteriów zapytania ograniczających zwracane dane za pomocą parametrów takich jak czas ostatniej aktualizacji.
Podobnie w przypadku pobierania obrazów warto zmniejszyć ich rozmiar po stronie serwera, zamiast pobierać obrazy w pełnym rozmiarze, które są zmniejszane po stronie klienta.
Zapisywanie w pamięci podręcznej odpowiedzi HTTP
Inną ważną techniką jest unikanie pobierania duplikatów danych. Możesz zmniejszyć prawdopodobieństwo wielokrotnego pobierania tych samych danych, korzystając z pamięci podręcznej. Dzięki buforowaniu danych i zasobów aplikacji tworzysz lokalną kopię informacji, do których aplikacja musi się odwoływać. Jeśli aplikacja musi uzyskać dostęp do tego samego elementu informacji kilka razy w krótkim czasie, musisz pobrać go do pamięci podręcznej tylko raz.
Ważne jest, aby jak najwięcej danych było przechowywane w pamięci podręcznej, ponieważ zmniejsza to łączną ilość pobieranych danych. Zawsze przechowuj w pamięci podręcznej zasoby statyczne, w tym zasoby do pobrania na żądanie, takie jak obrazy w pełnej rozdzielczości, tak długo, jak to możliwe. Zasoby na żądanie powinny być przechowywane oddzielnie, aby umożliwić regularne czyszczenie pamięci podręcznej na żądanie w celu zarządzania jej rozmiarem.
Aby mieć pewność, że przechowywanie w pamięci podręcznej nie powoduje wyświetlania przez aplikację nieaktualnych danych, używaj odpowiednich kodów stanu i nagłówków HTTP, takich jak nagłówki ETag
i Last-Modified
. Dzięki temu możesz określić, kiedy powiązane treści mają zostać odświeżone. Na przykład:
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; }
Niektóre biblioteki sieciowe możesz skonfigurować tak, aby automatycznie uwzględniały te kody stanu i nagłówki. Jeśli używasz na przykład OkHttp, skonfigurowanie katalogu pamięci podręcznej i jej rozmiaru dla klienta umożliwi bibliotece korzystanie z pamięci podręcznej HTTP, jak pokazano w tym przykładzie kodu:
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();
Po skonfigurowaniu pamięci podręcznej możesz wysyłać żądania HTTP w pełni zapisane w pamięci podręcznej bezpośrednio z pamięci lokalnej, bez konieczności nawiązywania połączenia sieciowego. Warunkowo zapisywane odpowiedzi w pamięci podręcznej mogą sprawdzać aktualność danych z serwera, eliminując koszty przepustowości związane z pobieraniem. Niebuforowane odpowiedzi są przechowywane w pamięci podręcznej odpowiedzi na potrzeby przyszłych żądań.
Aby umieścić w pamięci podręcznej dane niewrażliwe w katalogu niezarządzanej zewnętrznej pamięci podręcznej, użyj narzędzia Context.getExternalCacheDir()
.
Możesz też zapisać dane w zarządzanej, zabezpieczonej pamięci podręcznej aplikacji, używającContext.getCacheDir()
.
Pamiętaj, że ta wewnętrzna pamięć podręczna może zostać wyczyszczona, gdy systemowi zabraknie dostępnej pamięci.
Korzystanie z repozytorium
Jeśli chcesz zastosować bardziej zaawansowane podejście do buforowania, rozważ użycie wzorca Repository. Wymaga to utworzenia klasy niestandardowej znanej jako repozytorium, która zapewnia abstrakcję interfejsu API dla określonych danych lub zasobów. Repozytorium może początkowo pobierać swoje dane z różnych źródeł, takich jak zdalna usługa internetowa, ale przy kolejnych wywołaniach udostępnia elementom wywołującym ich wersję z pamięci podręcznej. Ta warstwa pośrednia umożliwia zapewnienie solidnej strategii buforowania specyficznej dla Twojej aplikacji. Więcej informacji o korzystaniu ze wzorca repozytorium w aplikacji znajdziesz w Przewodniku po architekturze aplikacji.