#android #kotlin #caching #retrofit2 #interceptor
#Android #kotlin #кэширование #обновление 2 #перехватчик
Вопрос:
Я пытаюсь реализовать перехватчик интернет-соединения с кэшированием, используя Retrofit и OkHttp.
Кэширование работает нормально без добавления перехватчика интернет-соединения, но когда я добавляю перехватчик интернет-соединения к клиенту OkHttp, перехватчик интернет-соединения работает нормально, но кэширование не работает.
Они отлично работают по отдельности, но когда я добавляю кэширование и интернет-перехватчик вместе, кэширование не работает, а перехватчик интернет-соединения работает.
Вот что я уже сделал:
val cacheSize = (5 * 1024 * 1024).toLong()
val myCache = Cache(context!!.cacheDir, cacheSize)
val okHttpClient = OkHttpClient.Builder()
.cache(myCache)
.addInterceptor(offlineInterceptor)
.addNetworkInterceptor(onlineInterceptor)
.addInterceptor(NoConnectionInterceptor(context))
.build()
Retrofit.Builder()
.baseUrl(Constants.REGISTRATION_BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
когда я удаляю NoConnectionInterceptor(context)
, кэширование работает нормально
var onlineInterceptor: Interceptor = object : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val response: Response = chain.proceed(chain.request())
val maxAge =
60 // read from cache for 60 seconds even if there is internet connection
return response.newBuilder()
.header("Cache-Control", "public, max-age=$maxAge")
.removeHeader("Pragma")
.build()
}
}
var offlineInterceptor: Interceptor = object : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
var request: Request = chain.request()
if (!hasNetwork()!!) {
val maxStale = 60 * 60 * 24 * 30 // Offline cache available for 30 days
request = request.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=$maxStale")
.removeHeader("Pragma")
.build()
}
return chain.proceed(request)
}
}
Класс NoConnectionInterceptorNoConnectionInterceptor
@Singleton
class NoConnectionInterceptor @Inject constructor(private val context: Context) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
return if (!isConnectionOn()) {
throw NoConnectivityException()
} else if (!isInternetAvailable()) {
throw NoInternetException()
} else {
chain.proceed(chain.request())
}
}
private fun isConnectionOn(): Boolean {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork
val connection = connectivityManager.getNetworkCapabilities(network)
return connection != null amp;amp; (
connection.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
connection.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
} else {
val activeNetwork = connectivityManager.activeNetworkInfo
if (activeNetwork != null) {
return (activeNetwork.type == ConnectivityManager.TYPE_WIFI ||
activeNetwork.type == ConnectivityManager.TYPE_MOBILE)
}
return false
}
}
private fun isInternetAvailable(): Boolean {
return try {
val timeoutMs = 1500
val sock = Socket()
val sockaddr = InetSocketAddress("8.8.8.8", 53)
sock.connect(sockaddr, timeoutMs)
sock.close()
true
} catch (e: IOException) {
false
}
}
class NoConnectivityException : IOException() {
override val message: String
get() = "No network available, please check your WiFi or Data connection"
}
class NoInternetException : IOException() {
override val message: String
get() = "No internet available, please check your connected WIFi or Data"
}
}
Комментарии:
1. Вы нашли какое-либо решение?