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

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

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

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

Кэшировать 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() . Обратите внимание, что этот внутренний кэш может быть очищен, когда в системе заканчивается доступное хранилище.

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

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