Publicado en Android

Implementar sistema de Cache con Retrofit, Android Kotlin


Usa Retrofit para hacer que su aplicación sea compatible sin conexión sin necesidad de implementar una base de datos.

El almacenamiento en caché es una forma de almacenar temporalmente datos extraídos de una petición de API, de modo que podamos acceder a ellos en un momento posterior cuando el dispositivo esté fuera de línea o si queremos acceder a los mismos datos nuevamente.

Creación de un OkHttpClient compatible con caché

Primero se necesita tener un método en nuestra aplicación que verifique la conectividad a Internet.

@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
fun isNetworkAvailable(context: Context): Boolean {
    val connectivityManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetwork = connectivityManager.activeNetwork ?: return false
    val networkCapabilities =
        connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
    return when {
        networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
        networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
        networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
        networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
        else -> false
    }
}

Definición de la caché

El siguiente código define un cache de 5MB

private val cacheSize = 5 * 1024 * 1024L //5 MB
private val myCache = Cache(MyApplication.instance.cacheDir, cacheSize)

Crear un interceptor para manejar la cache

Lo siguiente es crear un interceptor para manejar la cache, con el interceptor se podrá observar y modificar las solicitudes que salen y las respuestas correspondientes que regresan.

class CacheInterceptor(private val maxAge: Int, private val maxStale: Int) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
        var request = chain.request()

        request = if (MyNetworkUtils.isNetworkAvailable(MyApplication.instance)) {
            request.newBuilder().header(
                "Cache-Control",
                "public, max-age=$maxAge"
            ).build()
        } else {
            request.newBuilder().header(
                "Cache-Control",
                "public, only-if-cached, max-stale=$maxStale"
            ).build()
        }
        return chain.proceed(request)
    }

}

Para finalizar debermos asignar el Interceptor en el okHttpClient

private val okHttpClient = OkHttpClient.Builder()
    .cache(myCache)
    .addInterceptor(CacheInterceptor(MAX_AGE, MAX_STALE))
    .addInterceptor(OAuthInterceptor("Bearer", BuildConfig.ACCESS_TOKEN))
    .build()

private fun retrofit(): Retrofit = Retrofit.Builder()
    .baseUrl("API_URL")
    .addConverterFactory(GsonConverterFactory.create(gson))
    .client(okHttpClient)
    .build()

Las constantes MAX_AGE y MAX_STALE

  • MAX_AGE: La cantindad máxima en segundos que un recurso es cosiderado reciente.
  • MAX_STALE: Obtiene el valor de antigüedad máximo permitido para un recurso devuelto de la caché.
private const val MAX_AGE = 60 * 60 * 24
private const val MAX_STALE = 60 * 1

Autor:

Desarrollador freelance programador apasionado por el arte de programar, amante del auto aprendizaje y interesado por la tecnología en general.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios .