Избегайте неоптимизированных загрузок

Некоторые пользователи вашего приложения имеют непостоянный доступ к Интернету или имеют ограничения на объем информации, которую они могут загрузить на свои устройства. Вы можете побудить пользователей чаще взаимодействовать с вашим приложением, уменьшив объем данных, которые необходимо загрузить вашему приложению.

Самый фундаментальный способ сократить количество загрузок — загружать только то, что вам нужно. С точки зрения данных это означает внедрение REST API, которые позволяют вам указывать критерии запроса, ограничивающие возвращаемые данные, используя такие параметры, как время последнего обновления.

Аналогично, при загрузке изображений рекомендуется уменьшать размер изображений на стороне сервера, а не загружать полноразмерные изображения, которые уменьшаются на стороне клиента.

Кэшировать HTTP-ответы

Другой важный метод — избегать загрузки дублирующихся данных. Вы можете снизить вероятность повторной загрузки одного и того же фрагмента данных, используя кэширование. Кэшируя данные и ресурсы вашего приложения, вы создаете локальную копию информации, на которую должно ссылаться ваше приложение. Если вашему приложению необходимо получить доступ к одному и тому же фрагменту информации несколько раз в течение короткого периода времени, вам нужно загрузить его в кэш только один раз.

Важно кэшировать как можно более агрессивно, чтобы уменьшить общий объем загружаемых данных. Всегда кэшируйте статические ресурсы, включая загрузки по запросу, такие как полноразмерные изображения, на разумно возможный срок. Ресурсы по запросу следует хранить отдельно, чтобы вы могли регулярно очищать кэш по запросу для управления его размером.

Чтобы гарантировать, что кэширование не приведет к отображению устаревших данных в вашем приложении, используйте соответствующие коды статуса HTTP и заголовки , такие как заголовки ETag и Last-Modified . Это позволяет вам определить, когда следует обновить связанный контент. Например:

Котлин

// 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
}

Ява

// 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;
}

Вы можете настроить некоторые сетевые библиотеки для автоматического соблюдения этих кодов состояния и заголовков. Например, при использовании OkHttp настройка каталога кэша и размера кэша для клиента позволит библиотеке использовать кэширование HTTP, как показано в следующем примере кода:

Котлин

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

Ява

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

С настроенным кэшем вы можете обслуживать полностью кэшированные HTTP-запросы напрямую из локального хранилища, устраняя необходимость открывать сетевое соединение. Условно кэшированные ответы могут проверять свою свежесть с сервера, устраняя затраты на полосу пропускания, связанные с загрузкой. Некэшированные ответы сохраняются в кэше ответов для будущих запросов.

Вы можете кэшировать неконфиденциальные данные в неуправляемом внешнем кэш-каталоге с помощью Context.getExternalCacheDir() . В качестве альтернативы вы можете кэшировать данные в управляемом, безопасном кэше приложения с помощью Context.getCacheDir() . Обратите внимание, что этот внутренний кэш может быть очищен, когда в системе заканчивается доступное хранилище.

Использовать репозиторий

Для более сложного подхода к кэшированию рассмотрите шаблон проектирования Repository. Он включает создание пользовательского класса, известного как Repository, который предоставляет абстракцию API для некоторых конкретных данных или ресурсов. Репозиторий может изначально извлекать свои данные из различных источников, таких как удаленная веб-служба, но предоставляет вызывающим сторонам кэшированную версию данных в последующих вызовах. Этот уровень косвенности позволяет вам предоставить надежную стратегию кэширования, которая специфична для вашего приложения. Для получения дополнительной информации об использовании шаблона Repository в вашем приложении см. Руководство по архитектуре приложения .