diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/zip/ZipPool.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/zip/ZipPool.kt new file mode 100644 index 000000000..13f2ba8ca --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/zip/ZipPool.kt @@ -0,0 +1,32 @@ +package org.koitharu.kotatsu.core.zip + +import android.net.Uri +import androidx.annotation.WorkerThread +import androidx.collection.LruCache +import okhttp3.internal.closeQuietly +import okio.Source +import okio.source +import java.io.File +import java.util.zip.ZipFile + +class ZipPool(maxSize: Int) : LruCache(maxSize) { + + override fun entryRemoved(evicted: Boolean, key: String, oldValue: ZipFile, newValue: ZipFile?) { + super.entryRemoved(evicted, key, oldValue, newValue) + oldValue.closeQuietly() + } + + override fun create(key: String): ZipFile { + return ZipFile(File(key), ZipFile.OPEN_READ) + } + + @Synchronized + @WorkerThread + operator fun get(uri: Uri): Source { + val zip = requireNotNull(get(uri.schemeSpecificPart)) { + "Cannot obtain zip by \"$uri\"" + } + val entry = zip.getEntry(uri.fragment) + return zip.getInputStream(entry).source() + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt index 7403c9019..58d16e036 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt @@ -23,7 +23,6 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import okhttp3.OkHttpClient import okhttp3.Request -import okio.source import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.network.ImageProxyInterceptor import org.koitharu.kotatsu.core.network.MangaHttpClient @@ -39,6 +38,7 @@ import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug 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.core.zip.ZipPool import org.koitharu.kotatsu.local.data.CbzFilter import org.koitharu.kotatsu.local.data.PagesCache import org.koitharu.kotatsu.parsers.model.MangaPage @@ -47,7 +47,6 @@ import org.koitharu.kotatsu.reader.ui.pager.ReaderPage import java.io.File import java.util.LinkedList import java.util.concurrent.atomic.AtomicInteger -import java.util.zip.ZipFile import javax.inject.Inject import kotlin.coroutines.AbstractCoroutineContextElement import kotlin.coroutines.CoroutineContext @@ -74,6 +73,7 @@ class PageLoader @Inject constructor( private val prefetchLock = Mutex() private var repository: MangaRepository? = null private val prefetchQueue = LinkedList() + private val zipPool = ZipPool(2) private val counter = AtomicInteger(0) private var prefetchQueueLimit = PREFETCH_LIMIT_DEFAULT // TODO adaptive @@ -81,6 +81,7 @@ class PageLoader @Inject constructor( synchronized(tasks) { tasks.clear() } + zipPool.evictAll() } fun isPrefetchApplicable(): Boolean { @@ -196,14 +197,9 @@ class PageLoader @Inject constructor( val uri = Uri.parse(pageUrl) return if (CbzFilter.isUriSupported(uri)) { runInterruptible(Dispatchers.IO) { - ZipFile(uri.schemeSpecificPart) - }.use { zip -> - runInterruptible(Dispatchers.IO) { - val entry = zip.getEntry(uri.fragment) - zip.getInputStream(entry) - }.use { - cache.put(pageUrl, it.source()) - } + zipPool[uri] + }.use { + cache.put(pageUrl, it) } } else { val request = createPageRequest(page, pageUrl)