NTP-3108 | on-demand coil image cache clear (#12612)

This commit is contained in:
Mohit Rajput
2024-09-25 03:37:52 -07:00
committed by GitHub
parent 9a011cff98
commit b812bc3501
8 changed files with 146 additions and 32 deletions

View File

@@ -11,7 +11,7 @@ import coil.ImageLoader
import coil.ImageLoaderFactory
import com.navi.base.cache.repository.NaviCacheRepository
import com.navi.pay.common.setup.NaviPayManager
import com.naviapp.app.facades.ThirdPartyObjectProvider
import com.naviapp.app.facades.ImageLoaderProvider
import com.naviapp.app.initializers.ComponentInitializer
import com.naviapp.common.transformer.AppLoadTimerMapper
import com.naviapp.home.common.setup.NotificationManager
@@ -36,7 +36,7 @@ open class NaviApplication : BaseApplication(), ImageLoaderFactory {
@Inject
lateinit var componentInitializers: Lazy<List<@JvmSuppressWildcards ComponentInitializer>>
@Inject lateinit var thirdPartyObjectProvider: ThirdPartyObjectProvider
@Inject lateinit var imageLoaderProvider: ImageLoaderProvider
private val isDifferentPackageValue: Boolean by lazy {
isDifferentPackage(this@NaviApplication)
@@ -71,6 +71,5 @@ open class NaviApplication : BaseApplication(), ImageLoaderFactory {
fun getAppInForegroundCounter() = appForegroundCounter
override fun newImageLoader(): ImageLoader =
thirdPartyObjectProvider.createImageLoader(applicationContext)
override fun newImageLoader(): ImageLoader = imageLoaderProvider.createImageLoader()
}

View File

@@ -0,0 +1,17 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.app.facades
import com.naviapp.app.image.CoilImageLibraryHandler
import javax.inject.Inject
class ImageLoaderProvider
@Inject
constructor(private val coilImageLibraryHandler: CoilImageLibraryHandler) {
fun createImageLoader() = coilImageLibraryHandler.createImageLoader()
}

View File

@@ -1,26 +0,0 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.app.facades
import android.content.Context
import coil.ImageLoader
import coil.decode.SvgDecoder
import coil.request.CachePolicy
import javax.inject.Inject
class ThirdPartyObjectProvider @Inject constructor() {
fun createImageLoader(context: Context): ImageLoader {
return ImageLoader.Builder(context)
.components { add(SvgDecoder.Factory()) }
.respectCacheHeaders(enable = false)
.diskCachePolicy(CachePolicy.ENABLED)
.memoryCachePolicy(CachePolicy.ENABLED)
.allowHardware(false)
.build()
}
}

View File

@@ -0,0 +1,61 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.app.image
import android.content.Context
import coil.ImageLoader
import coil.annotation.ExperimentalCoilApi
import coil.decode.SvgDecoder
import coil.imageLoader
import coil.memory.MemoryCache
import coil.request.CachePolicy
import com.navi.common.di.CoroutineDispatcherProvider
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import kotlinx.coroutines.withContext
class CoilImageLibraryHandler
@Inject
constructor(
@ApplicationContext private val context: Context,
private val coroutineDispatcherProvider: CoroutineDispatcherProvider
) : ImageLibraryHandler {
fun createImageLoader(): ImageLoader {
return ImageLoader.Builder(context)
.components { add(SvgDecoder.Factory()) }
.respectCacheHeaders(enable = false)
.diskCachePolicy(CachePolicy.ENABLED)
.memoryCachePolicy(CachePolicy.ENABLED)
.allowHardware(false)
.build()
}
@OptIn(ExperimentalCoilApi::class)
override suspend fun removeImageCache(imageUrl: String) {
withContext(coroutineDispatcherProvider.io) {
context.imageLoader.apply {
memoryCache?.remove(MemoryCache.Key(key = imageUrl))
diskCache?.remove(key = diskCacheKey(imageUrl))
}
}
}
private fun diskCacheKey(imageUrl: String): String {
return imageUrl.hashCode().toString()
}
@OptIn(ExperimentalCoilApi::class)
override suspend fun clearImageCache() {
withContext(coroutineDispatcherProvider.io) {
context.imageLoader.apply {
memoryCache?.clear()
diskCache?.clear()
}
}
}
}

View File

@@ -0,0 +1,14 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.app.image
interface ImageLibraryHandler {
suspend fun removeImageCache(imageUrl: String)
suspend fun clearImageCache()
}

View File

@@ -0,0 +1,27 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.common.di
import com.naviapp.app.image.CoilImageLibraryHandler
import com.naviapp.app.image.ImageLibraryHandler
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
interface AppBindingModule {
@Singleton
@Binds
fun bindImageLibraryHandler(
coilImageLibraryHandler: CoilImageLibraryHandler
): ImageLibraryHandler
}

View File

@@ -45,6 +45,7 @@ import com.navi.common.utils.log
import com.navi.pay.common.utils.NaviPayNotificationHandler
import com.naviapp.R
import com.naviapp.app.NaviApplication
import com.naviapp.app.image.ImageLibraryHandler
import com.naviapp.common.navigator.NaviDeepLinkNavigator.CHAT_ACTIVITY
import com.naviapp.deeplinkmanagement.ui.DeeplinkManagementActivity
import com.naviapp.pushnotification.NotificationHandler
@@ -59,6 +60,7 @@ import com.naviapp.utils.FCM_TOKEN
import com.naviapp.utils.deleteCacheAndOpenLoginPage
import com.naviapp.utils.isNetworkAvailable
import java.util.Random
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -68,6 +70,8 @@ import timber.log.Timber
class NaviFirebaseMessagingService : FirebaseMessagingService() {
private val fcmCallbackRepository by lazy { FcmCallbackRepository() }
@Inject lateinit var imageLibraryHandler: ImageLibraryHandler
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
handleNotificationData(remoteMessage, applicationContext)
@@ -172,14 +176,14 @@ class NaviFirebaseMessagingService : FirebaseMessagingService() {
cancelPushNotification(context, data)
}
NotificationConstants.SILENT_PN -> {
handleSilentNotificationAction(context, data)
handleSilentNotificationAction(data)
}
}
}
}
}
private fun handleSilentNotificationAction(context: Context, data: Map<String, String>) {
private fun handleSilentNotificationAction(data: Map<String, String>) {
data[NotificationConstants.ACTION]?.let { action ->
when (action) {
NotificationConstants.CLEAR_TASK -> clearTask()
@@ -192,6 +196,19 @@ class NaviFirebaseMessagingService : FirebaseMessagingService() {
NotificationConstants.CLEAR_SHARED_DB_WITH_KEYS -> {
clearSharedDbWithKeys(data[NotificationConstants.SHARED_DB_KEYS])
}
NotificationConstants.REMOVE_SPECIFIC_IMAGE_CACHE -> {
CoroutineScope(Dispatchers.IO).launch {
data[NotificationConstants.COMMA_SEPARATED_IMAGE_URLS]
.orEmpty()
.split(COMMA)
.forEach { imageUrl ->
imageLibraryHandler.removeImageCache(imageUrl = imageUrl)
}
}
}
NotificationConstants.CLEAR_IMAGE_CACHE -> {
CoroutineScope(Dispatchers.IO).launch { imageLibraryHandler.clearImageCache() }
}
}
NaviTrackEvent.trackEventOnClickStream(
Constants.SILENT_PN_ACTION,

View File

@@ -37,4 +37,9 @@ object NotificationConstants {
const val CLEAR_ALL_SHARED_DB = "clearAllSharedDb"
const val CLEAR_SHARED_DB_WITH_KEYS = "clearSharedDbWithKeys"
const val SHARED_DB_KEYS = "sharedDbKeys"
// Cache clear constants
const val REMOVE_SPECIFIC_IMAGE_CACHE = "removeSpecificImageCache"
const val COMMA_SEPARATED_IMAGE_URLS = "commaSeparatedImageUrls"
const val CLEAR_IMAGE_CACHE = "clearImageCache"
}