Check available ram before pages prefetch
This commit is contained in:
@@ -54,9 +54,10 @@ class PagesCache @Inject constructor(@ApplicationContext context: Context) {
|
|||||||
suspend fun put(url: String, source: Source): File = withContext(Dispatchers.IO) {
|
suspend fun put(url: String, source: Source): File = withContext(Dispatchers.IO) {
|
||||||
val file = File(cacheDir.get().parentFile, url.longHashCode().toString())
|
val file = File(cacheDir.get().parentFile, url.longHashCode().toString())
|
||||||
try {
|
try {
|
||||||
file.sink(append = false).buffer().use {
|
val bytes = file.sink(append = false).buffer().use {
|
||||||
it.writeAllCancellable(source)
|
it.writeAllCancellable(source)
|
||||||
}
|
}
|
||||||
|
check(bytes != 0L) { "No data has been written" }
|
||||||
lruCache.get().put(url, file)
|
lruCache.get().put(url, file)
|
||||||
} finally {
|
} finally {
|
||||||
file.delete()
|
file.delete()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.koitharu.kotatsu.reader.domain
|
package org.koitharu.kotatsu.reader.domain
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@@ -8,6 +9,7 @@ import androidx.collection.LongSparseArray
|
|||||||
import androidx.collection.set
|
import androidx.collection.set
|
||||||
import dagger.hilt.android.ActivityRetainedLifecycle
|
import dagger.hilt.android.ActivityRetainedLifecycle
|
||||||
import dagger.hilt.android.lifecycle.RetainedLifecycle
|
import dagger.hilt.android.lifecycle.RetainedLifecycle
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -30,8 +32,10 @@ import org.koitharu.kotatsu.parsers.model.MangaPage
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.parsers.util.await
|
import org.koitharu.kotatsu.parsers.util.await
|
||||||
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
|
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
|
||||||
|
import org.koitharu.kotatsu.utils.FileSize
|
||||||
import org.koitharu.kotatsu.utils.RetainedLifecycleCoroutineScope
|
import org.koitharu.kotatsu.utils.RetainedLifecycleCoroutineScope
|
||||||
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
||||||
|
import org.koitharu.kotatsu.utils.ext.ramAvailable
|
||||||
import org.koitharu.kotatsu.utils.ext.withProgress
|
import org.koitharu.kotatsu.utils.ext.withProgress
|
||||||
import org.koitharu.kotatsu.utils.progress.ProgressDeferred
|
import org.koitharu.kotatsu.utils.progress.ProgressDeferred
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -44,9 +48,11 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
|
|
||||||
private const val PROGRESS_UNDEFINED = -1f
|
private const val PROGRESS_UNDEFINED = -1f
|
||||||
private const val PREFETCH_LIMIT_DEFAULT = 10
|
private const val PREFETCH_LIMIT_DEFAULT = 10
|
||||||
|
private const val PREFETCH_MIN_RAM_MB = 80L
|
||||||
|
|
||||||
@ActivityRetainedScoped
|
@ActivityRetainedScoped
|
||||||
class PageLoader @Inject constructor(
|
class PageLoader @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
lifecycle: ActivityRetainedLifecycle,
|
lifecycle: ActivityRetainedLifecycle,
|
||||||
private val okHttp: OkHttpClient,
|
private val okHttp: OkHttpClient,
|
||||||
private val cache: PagesCache,
|
private val cache: PagesCache,
|
||||||
@@ -75,7 +81,7 @@ class PageLoader @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isPrefetchApplicable(): Boolean {
|
fun isPrefetchApplicable(): Boolean {
|
||||||
return repository is RemoteMangaRepository && settings.isPagesPreloadEnabled()
|
return repository is RemoteMangaRepository && settings.isPagesPreloadEnabled() && !isLowRam()
|
||||||
}
|
}
|
||||||
|
|
||||||
@AnyThread
|
@AnyThread
|
||||||
@@ -116,6 +122,9 @@ class PageLoader @Inject constructor(
|
|||||||
|
|
||||||
suspend fun convertInPlace(file: File) {
|
suspend fun convertInPlace(file: File) {
|
||||||
convertLock.withLock {
|
convertLock.withLock {
|
||||||
|
if (context.ramAvailable < file.length() * 2) {
|
||||||
|
return@withLock
|
||||||
|
}
|
||||||
runInterruptible(Dispatchers.Default) {
|
runInterruptible(Dispatchers.Default) {
|
||||||
val image = BitmapFactory.decodeFile(file.absolutePath)
|
val image = BitmapFactory.decodeFile(file.absolutePath)
|
||||||
try {
|
try {
|
||||||
@@ -212,6 +221,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),
|
private class InternalErrorHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler),
|
||||||
CoroutineExceptionHandler {
|
CoroutineExceptionHandler {
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.utils.ext
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
|
import android.app.ActivityManager.MemoryInfo
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Context.ACTIVITY_SERVICE
|
import android.content.Context.ACTIVITY_SERVICE
|
||||||
@@ -138,6 +139,13 @@ fun isLowRamDevice(context: Context): Boolean {
|
|||||||
return context.activityManager?.isLowRamDevice ?: false
|
return context.activityManager?.isLowRamDevice ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val Context.ramAvailable: Long
|
||||||
|
get() {
|
||||||
|
val result = MemoryInfo()
|
||||||
|
activityManager?.getMemoryInfo(result)
|
||||||
|
return result.availMem
|
||||||
|
}
|
||||||
|
|
||||||
fun scaleUpActivityOptionsOf(view: View): ActivityOptions = ActivityOptions.makeScaleUpAnimation(
|
fun scaleUpActivityOptionsOf(view: View): ActivityOptions = ActivityOptions.makeScaleUpAnimation(
|
||||||
view,
|
view,
|
||||||
0,
|
0,
|
||||||
|
|||||||
Reference in New Issue
Block a user