Кэширование относится к временному хранению данных, полученных из сети, в хранилище устройства, что позволяет нам получить к ним доступ позже, либо когда устройство находится в автономном режиме, либо когда нам нужно снова получить те же данные.
В этом блоге мы узнаем, как реализовать кеширование в вашем приложении для Android с помощью OkHttp Interceptor и Retrofit, что позволит вам временно хранить ответы для последующего использования без необходимости в базе данных!
Давайте рассмотрим, как кэширование может повысить производительность наших приложений для Android.
- Когда мы запрашиваем данные с сервера через сетевой вызов,
- первый запрос извлечет данные с сервера и сохранит ответ HTTP в кеше клиента.
- Впоследствии, если мы снова сделаем тот же вызов API, он мгновенно вернет данные из кеша.
Приступим к практической части этой статьи.
В настоящее время мы используем такие модификации, как:
val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build()
Как мы знаем, приведенная выше модернизация использует OkHttpClient
по умолчанию, который не использует кеш, поэтому нам нужно создать экземпляр OkHttpClient
, который поддерживает кеширование и может эффективно обрабатывать выборку данных, когда:
- Отсутствует подключение к Интернету,и
- Приложению необходимо получить доступ к одним и тем же данным из сети в течение короткого периода времени.
Теперь давайте создадим дружественный к кэшу OkHttpClient.
Шаг 1. Создайте размер кэша и кэш.
val cacheSize = (10 * 1024 * 1024).toLong() // 10MB val myCache = Cache(context.cacheDir, cacheSize)
Шаг 2. Определите метод проверки подключения к Интернету
Нам нужен метод в нашем приложении, который проверяет подключение к Интернету. Это шаблонный код, но вот он,
fun hasNetwork(context: Context): Boolean? { var isConnected: Boolean? = false // Initial Value val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo if (activeNetwork != null && activeNetwork.isConnected) isConnected = true return isConnected }
Шаг 3: Давайте создадим перехватчик
OkHttp поставляется с мощным компонентом Interceptors.
У нас есть два типа перехватчиков:
- Перехватчики приложений: это перехватчики, которые добавляются между кодом приложения (нашим письменным кодом) и базовой библиотекой OkHttp. Это те, которые мы добавляем с помощью addInterceptor().
- Сетевые перехватчики. Это перехватчики, которые добавляются между основной библиотекой OkHttp и сервером. Их можно добавить в OkHttpClient с помощью addNetworkInterceptor().
теперь мы создадим перехватчик, как показано ниже:
// this for only response interceptor is invoked for online responses val REWRITE_RESPONSE_INTERCEPTOR = Interceptor { chain -> val originalResponse = chain.proceed(chain.request()) val maxAge = 60 // read from cache for 60 seconds even if there is internet connection val cacheControl = originalResponse.header("Cache-Control") if (cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") || cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0") ) { originalResponse.newBuilder() .removeHeader("Pragma") .header("Cache-Control", "public, max-age=$maxAge") .build() } else { originalResponse } } val REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = Interceptor { chain -> var request = chain.request() if (!hasNetwork(context)) { val maxStale = 60 * 60 * 24 * 30 // Offline cache available for 30 days request = request.newBuilder() .removeHeader("Pragma") .header("Cache-Control", "public, only-if-cached=$maxStale") // The 'only-if-cached' attribute indicates to not retrieve new data; fetch the cache only instead. .build() } chain.proceed(request) }
Шаг 4. Создайте экземпляр OkHttpClient, определите кеш и добавьте перехватчики.
val okHttpClient = OkHttpClient.Builder().apply { cache(myCache) addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE) addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR) }
Теперь нам нужно добавить этот только что созданный OkHttpClient
в наш экземпляр Retrofit
.
val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) // Adding our OkHttpClient .client(okHttpClient) .build()
Именно так мы можем кэшировать HTTP-ответы в Android, используя OkHttp Interceptor и Retrofit.
Спасибо за прочтение и счастливого кодирования! 😊
Не забывайте 👏