Check available ram before pages prefetch

This commit is contained in:
Koitharu
2023-06-02 15:29:55 +03:00
parent 893ba37c86
commit b1187c611a
3 changed files with 24 additions and 4 deletions

View File

@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.util.ext
import android.app.Activity
import android.app.ActivityManager
import android.app.ActivityManager.MemoryInfo
import android.app.ActivityOptions
import android.content.Context
import android.content.Context.ACTIVITY_SERVICE
@@ -23,8 +24,6 @@ import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.IntegerRes
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.IntentCompat
import androidx.core.content.PackageManagerCompat
import androidx.core.os.LocaleListCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
@@ -142,6 +141,13 @@ fun Context.isLowRamDevice(): Boolean {
return activityManager?.isLowRamDevice ?: false
}
val Context.ramAvailable: Long
get() {
val result = MemoryInfo()
activityManager?.getMemoryInfo(result)
return result.availMem
}
fun scaleUpActivityOptionsOf(view: View): ActivityOptions = ActivityOptions.makeScaleUpAnimation(
view,
0,

View File

@@ -54,9 +54,10 @@ class PagesCache @Inject constructor(@ApplicationContext context: Context) {
suspend fun put(url: String, source: Source): File = withContext(Dispatchers.IO) {
val file = File(cacheDir.get().parentFile, url.longHashCode().toString())
try {
file.sink(append = false).buffer().use {
val bytes = file.sink(append = false).buffer().use {
it.writeAllCancellable(source)
}
check(bytes != 0L) { "No data has been written" }
lruCache.get().put(url, file)
} finally {
file.delete()

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.reader.domain
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
@@ -8,6 +9,7 @@ import androidx.collection.LongSparseArray
import androidx.collection.set
import dagger.hilt.android.ActivityRetainedLifecycle
import dagger.hilt.android.lifecycle.RetainedLifecycle
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ActivityRetainedScoped
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Dispatchers
@@ -27,8 +29,10 @@ import org.koitharu.kotatsu.core.network.MangaHttpClient
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.FileSize
import org.koitharu.kotatsu.core.util.RetainedLifecycleCoroutineScope
import org.koitharu.kotatsu.core.util.ext.ensureSuccess
import org.koitharu.kotatsu.core.util.ext.ramAvailable
import org.koitharu.kotatsu.core.util.ext.withProgress
import org.koitharu.kotatsu.core.util.progress.ProgressDeferred
import org.koitharu.kotatsu.local.data.CbzFilter
@@ -47,6 +51,7 @@ import kotlin.coroutines.CoroutineContext
@ActivityRetainedScoped
class PageLoader @Inject constructor(
@ApplicationContext private val context: Context,
lifecycle: ActivityRetainedLifecycle,
@MangaHttpClient private val okHttp: OkHttpClient,
private val cache: PagesCache,
@@ -76,7 +81,7 @@ class PageLoader @Inject constructor(
}
fun isPrefetchApplicable(): Boolean {
return repository is RemoteMangaRepository && settings.isPagesPreloadEnabled
return repository is RemoteMangaRepository && settings.isPagesPreloadEnabled && !isLowRam()
}
@AnyThread
@@ -117,6 +122,9 @@ class PageLoader @Inject constructor(
suspend fun convertInPlace(file: File) {
convertLock.withLock {
if (context.ramAvailable < file.length() * 2) {
return@withLock
}
runInterruptible(Dispatchers.Default) {
val image = BitmapFactory.decodeFile(file.absolutePath)
try {
@@ -204,6 +212,10 @@ class PageLoader @Inject constructor(
}
}
private fun isLowRam(): Boolean {
return context.ramAvailable <= FileSize.MEGABYTES.convert(PREFETCH_MIN_RAM_MB, FileSize.BYTES)
}
private class InternalErrorHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler),
CoroutineExceptionHandler {
@@ -216,6 +228,7 @@ class PageLoader @Inject constructor(
private const val PROGRESS_UNDEFINED = -1f
private const val PREFETCH_LIMIT_DEFAULT = 10
private const val PREFETCH_MIN_RAM_MB = 80L
fun createPageRequest(page: MangaPage, pageUrl: String) = Request.Builder()
.url(pageUrl)