From bdb2ae9c2f0a9afd6209b7cdc94f421b906922df Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 4 Jan 2023 08:28:46 +0200 Subject: [PATCH] Manage prefetch cache memory --- .../org/koitharu/kotatsu/core/AppModule.kt | 6 +-- .../kotatsu/core/cache/ContentCache.kt | 2 + .../kotatsu/core/cache/MemoryContentCache.kt | 38 +++++++++++++++++-- .../kotatsu/core/cache/StubContentCache.kt | 2 + .../details/service/MangaPrefetchService.kt | 6 +-- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt b/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt index 8a39c05a1..4ee31403a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt @@ -190,12 +190,12 @@ interface AppModule { @Provides @Singleton fun provideContentCache( - @ApplicationContext context: Context, + application: Application, ): ContentCache { - return if (context.activityManager?.isLowRamDevice == true) { + return if (application.activityManager?.isLowRamDevice == true) { StubContentCache() } else { - MemoryContentCache() + MemoryContentCache(application) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/cache/ContentCache.kt b/app/src/main/java/org/koitharu/kotatsu/core/cache/ContentCache.kt index 56a6f740e..f9c37b2c3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/cache/ContentCache.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/cache/ContentCache.kt @@ -7,6 +7,8 @@ import org.koitharu.kotatsu.parsers.model.MangaSource interface ContentCache { + val isCachingEnabled: Boolean + suspend fun getDetails(source: MangaSource, url: String): Manga? fun putDetails(source: MangaSource, url: String, details: Deferred) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt b/app/src/main/java/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt index ed1b46ac1..4fb146d22 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt @@ -1,15 +1,24 @@ package org.koitharu.kotatsu.core.cache +import android.app.Application +import android.content.ComponentCallbacks2 +import android.content.res.Configuration import kotlinx.coroutines.Deferred import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.model.MangaSource @Suppress("DeferredResultUnused") -class MemoryContentCache : ContentCache { +class MemoryContentCache(application: Application) : ContentCache, ComponentCallbacks2 { - private val detailsCache = DeferredLruCache(10) - private val pagesCache = DeferredLruCache>(10) + init { + application.registerComponentCallbacks(this) + } + + private val detailsCache = DeferredLruCache(4) + private val pagesCache = DeferredLruCache>(4) + + override val isCachingEnabled: Boolean = true override suspend fun getDetails(source: MangaSource, url: String): Manga? { return detailsCache[ContentCache.Key(source, url)]?.await() @@ -26,4 +35,27 @@ class MemoryContentCache : ContentCache { override fun putPages(source: MangaSource, url: String, pages: Deferred>) { pagesCache.put(ContentCache.Key(source, url), pages) } + + override fun onConfigurationChanged(newConfig: Configuration) = Unit + + override fun onLowMemory() = Unit + + override fun onTrimMemory(level: Int) { + trimCache(detailsCache, level) + trimCache(pagesCache, level) + } + + private fun trimCache(cache: DeferredLruCache<*>, level: Int) { + when (level) { + ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL, + ComponentCallbacks2.TRIM_MEMORY_COMPLETE, + ComponentCallbacks2.TRIM_MEMORY_MODERATE -> cache.evictAll() + + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN, + ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW, + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND -> cache.trimToSize(1) + + else -> cache.trimToSize(cache.maxSize() / 2) + } + } } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/cache/StubContentCache.kt b/app/src/main/java/org/koitharu/kotatsu/core/cache/StubContentCache.kt index cd3d632be..faf9a7237 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/cache/StubContentCache.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/cache/StubContentCache.kt @@ -7,6 +7,8 @@ import org.koitharu.kotatsu.parsers.model.MangaSource class StubContentCache : ContentCache { + override val isCachingEnabled: Boolean = false + override suspend fun getDetails(source: MangaSource, url: String): Manga? = null override fun putDetails(source: MangaSource, url: String, details: Deferred) = Unit diff --git a/app/src/main/java/org/koitharu/kotatsu/details/service/MangaPrefetchService.kt b/app/src/main/java/org/koitharu/kotatsu/details/service/MangaPrefetchService.kt index 225d1042c..6af5e3258 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/service/MangaPrefetchService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/service/MangaPrefetchService.kt @@ -9,7 +9,6 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import org.koitharu.kotatsu.base.ui.CoroutineIntentService import org.koitharu.kotatsu.core.cache.ContentCache -import org.koitharu.kotatsu.core.cache.StubContentCache import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga import org.koitharu.kotatsu.core.model.parcelable.ParcelableMangaChapters import org.koitharu.kotatsu.core.parser.MangaRepository @@ -87,10 +86,7 @@ class MangaPrefetchService : CoroutineIntentService() { return false } val entryPoint = EntryPointAccessors.fromApplication(context, PrefetchCompanionEntryPoint::class.java) - if (entryPoint.contentCache is StubContentCache) { - return false - } - return entryPoint.settings.isContentPrefetchEnabled() + return entryPoint.contentCache.isCachingEnabled && entryPoint.settings.isContentPrefetchEnabled() } } }